Python 3.10 有哪些新特性 ?
Python中文社區(ID:python-china)
Python 3.10 的開發已經穩定下來,我們終于可以測試最終版本中將包含的所有新功能。下面我們將介紹 Python 3.10 中最有趣的一些新增功能——結構模式匹配、帶括號的上下文管理器、 更多類型以及新的報錯消息。
結構模式匹配
結構模式匹配是要添加到 Python 中的一個很棒的功能。想象一個如下所示的 if-else 語句(Python 3.9):
- http_code = "418"
- if http_code == "200":
- print("OK")
- elif http_code == "404":
- print("Not Found")
- elif http_code == "418":
- print("I'm a teapot")
- else:
- print("Code not found")
輸出:
- I'm a teapot
Python 3.10 中可以這樣寫:
- http_code = "418"
- match http_code:
- case"200":
- print("OK")
- case"404":
- print("Not Found")
- case"418":
- print("I'm a teapot")
- case _:
- print("Code not found")
這就是新的 match-case語句——很酷,但目前還沒有什么特別之處。使 match-case語句如此有趣的原因是一種稱為結構模式匹配的東西。結構模式匹配允許我們執行相同的 match-case 邏輯,但基于我們的比較對象的結構是否與給定的模式匹配。
因此,讓我們定義兩個字典,它們都具有不同的結構。
- dict_a = {
- 'id': 1,
- 'meta': {
- 'source': 'abc',
- 'location': 'west'
- }
- }
- dict_b = {
- 'id': 2,
- 'source': 'def',
- 'location': 'west'
- }
現在,我們可以編寫一個模式來匹配 dict_a,如下所示:
- {
- 'id': int,
- 'meta': {'source': str,
- 'location': str}
- }
還有一個匹配 dict_b的模式:
- {
- 'id': int,
- 'source': str,
- 'location': str
- }
如果我們將這兩個放在一個 match-case語句中,以及有效的 else/和包羅萬象的 case_ - 我們得到:
- # loop through both dictionaries and a 'test'
- for d in[dict_a, dict_b, 'test']:
- match d:
- case{'id': ident,
- 'meta': {'source': source,
- 'location': loc}}:
- print(ident, source, loc)
- case{'id': ident,
- 'source': source,
- 'location': loc}:
- print(ident, source, loc)
- case _:
- print('no match')
輸出結果:
- 1 abc west
- 2def west
- no match
是不是很酷?我已經發現這對數據處理非常有用。
帶括號的上下文管理器
一個較小的變化是新的基于 PEG 的解析器。以前的 Python 解釋器有很多限制,這限制了 Python 開發人員可以使用的語法。
Python 3.9 的基于 PEG 的解析器消除了這些障礙,從長遠來看,這可能會導致更優雅的語法——這種變化的第一個例子是新的帶括號的上下文管理器。在 Python 3.9 之前,我們可以寫這樣的東西來打開兩個(或更多)文件 I/O 流:
- with open('file1.txt', 'r') as fin, open('file2.txt', 'w') as fout:
- fout.write(fin.read())
第一行很長。但是由于解析器的限制,我們可以將此行拆分為多行的唯一方法是使用 \ 行繼續符:
- with open('file1.txt', 'r') as fin, \
- open('file2.txt', 'w') as fout:
- fout.write(fin.read())
它是有效的,但不是很 Pythonic。使用新的解析器,我們現在可以將括號將這一行拆分為多行,如下所示:
- with(open('file1.txt', 'r') as fin,
- open('file2.txt', 'w') as fout):
- fout.write(fin.read())
這種寫法很Pythonic?,F在,在我們繼續,如果我們寫:
- with(open('file1.txt', 'r') as fin,
- open('file2.txt', 'w') as fout):
- fout.write(fin.read())
在 Python 3.9 中也可以這樣寫。這是因為新的解析器啟用了這種語法,盡管直到 Python 3.10 才被正式支持。
Typing功能
Python 的輸入功能也有更多更新。這里最有趣的添加是包含了一個新的運算符,它的行為類似于類型的 OR 邏輯,我們之前使用 Union 方法來實現:
- from typing importUnion
- def add(x: Union[int, float], y: Union[int, float]):
- return x + y
現在,我們不需要寫成 fromtypingimportUnion,并且 Union[int,float] 已經簡化為 int|float,看起來更簡潔:
- def add(x: int| float, y: int| float):
- return x + y
更加完善的報錯信息
相信你第一次看到時都會去百度或者 Google 搜索:
- SyntaxError: unexpected EOF while parsing
輸入 SyntaxError 時,Google 中排名第一的結果表明我們中的許多人確實在某個時候做過。
這不是一條明確的報錯消息,Python 中充滿了不太明確的報錯消息。幸運的是,有人注意到了它們——其中許多消息都得到了顯著改善。
官方更改列表中提到了更多改動 - 但在測試期間似乎沒有顯示,包括:
- from collections import namedtoplo
- > AttributeError: module'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?
在這里, AttributeError 與之前相同,但增加了一個建議的屬性名稱—— namedtoplo 被標識為屬性 namedtuple的潛在拼寫錯誤。
同樣,我們看到 NameError消息也有相同的改進:
- new_var = 5
- print(new_vr)
- > NameError: name 'new_vr'isnotdefined. Did you mean: new_var?
總結
以上是 Python 3.10 引入的一些關鍵新功能!
完整版本預計于 2021 年 10 月 4 日發布,從現在開始,Python 開發人員將致力于改進已經添加的內容——但不會引入新功能。如果您想自己檢查一下,可以從這里下載 3.10.0b1。