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