國慶假期,Python 社區發佈了 3.9 版本的第一個 stable release。
相比於 3.8,Python 3.9 新特性衆多,但不少特性與大多數 Python“使用者”(而非 CPython 的貢獻者或使用 C 接口編寫擴展的開發者)關係不大。
本文將站在 Python “使用者”的角度,簡單介紹新特性中很可能會與各位的日常開發產生關係的幾個。
字典“並集”運算符
“並集”運算符顧名思義就是給兩個字典取並,併產生新的字典對象。
熟悉 collections 標準庫的開發者聽到這一特性想必很容易聯想到 ChainMap,兩者的區別是“並集”運算符會直接產生新的對象,而 ChainMap 產生的是與輸入的對象相關聯的視圖——視圖對象或輸入對象的變化都會直接對對方產生影響。
字典“並集”運算符及其相對應的原地運算符的效果如圖:
也許有同學會質疑“並集”運算符的意義,畢竟使用如下的寫法也能相對簡潔地合併字典:
就筆者的理解(且不提上述三種寫法有多少開發者能夠想到),“並集”運算符的優勢在於不會丟失參與合併字典的類型信息,且對字典鍵的類型沒有要求;
此外,經過簡單測試,“並集”運算符在性能上也更有優勢。
類型提示的改善
Python 3.9 爲內置的以及標準庫中的集合類型提供了用於類型提示中的泛型的支持。如:
這一支持解決了一直以來 Python 代碼中會出現兩種 list(list 和 typing.List)類型的尷尬情況。需要注意的是,泛型化的內置類型仍然支持實例化,但不能被用於 isinstance 和 issubclass 判斷,這一設計應該 Python 社區是結合了代碼表意性和性能作出的綜合考量:
此外,typing 庫加入了新的類型 Annotated,通過使用 Annotated,開發者可以爲內置的或自定義的類型附加更多的信息。
一種可能的使用場景:Annotated 中的類型信息供 IDE 或 代碼審查工具靜態地檢查變量類型,而附加的信息則可以在運行時產生更豐富的作用——PEP 593 中展示了一個類似的例子。
查看PEP 593:
https://www.python.org/dev/peps/pep-0593/#combining-runtime-and-static-uses-of-annotations
裝飾器語法更加靈活
舊版本的 Python 對裝飾器的語法有所限制,Python 3.9 將這一限制放寬——任意“表達式”均可用在裝飾器中。
如果讀者對“任意表達式”這一概念感到模糊,可以參考 if 或 while 語句,在 Python 3.9 中,任意可以用在 if 或 while 測試部分的語句都可以成爲裝飾器而不會產生語法錯誤。
如下圖所示,甚至匿名函數也可以直接作爲裝飾器(雖然圖中的做法毫無意義,在此僅僅爲了演示語法特性),在 Python 3.8 或之前的版本中,這樣的寫法會引發 SyntaxError。
PEP-614 爲我們展示了一個更有實用價值的例子 —— 在編寫 PyQt5 代碼時爲按鈕列表中的每個元素分別註冊事件。
查看PEP 614:
https://www.python.org/dev/peps/pep-0614/#motivation
classmethod 支持包裝其他描述器
Python3.9 中的 classmethod 函數增加了對包裝其他描述器(descriptor)的支持。
如下圖所示,現在我們可以結合 classmethod 和 property 輕鬆創造出一個類的屬性(在 3.8 及之前的版本中,開發者需要手工實現一個描述器以支持類似的功能)。
新增模塊、函數、方法
包括且不限於:
- 標準庫中添加了時區數據庫模塊 zoneinfo
- 內置的字符串類型加入了新的掐頭去尾方法 removeprefix 和 removesuffix
- math 模塊中新增了多個數學運算函數
參考資料
1.Python.org
2.Python Enhancement Proposals (PEPs)
3.Python Documentation
4.
上文中介紹的特性僅僅是 Python 3.9 更新中的冰山一角,想要更全面地瞭解 Python 3.9,您可以:
-
直接訪問文檔
https://docs.python.org/3.9/whatsnew/3.9.html#what-s-new-in-python-3-9 -
下載 Python3.9 的安裝器或源碼(anaconda 頻道中尚未提供 Python 3.9)自行體驗。