摘要:2020年10月5日,在全國人員歡度國慶節和中秋節時,Python 3.9 悄摸摸地正式發佈了。
2020年10月5日,在全國人員歡度國慶節和中秋節時,Python 3.9 悄摸摸地正式發佈了。咱們來一塊兒來看看,這個版本有哪些好玩的新特性,以及對咱們部門目前的產品可能會帶來哪些影響。html
由於jupyter notebook/lab等工具尚未相應適配到python 3.9,因此咱們還沒法使用,所以本文就使用python 的交互行來演示。python
Python 3.9 官方文檔, What’s New in Python 3.9 ,其文字組織的很好,咱們接下來也按照這個順序來說解,依次是,release highlights, new features, new modules, improve modules, optimizations, deprecated, removed.你們注意看下,這個文字組織順序,其實在咱們產品發佈時,也是適用的。先講這個版本有什麼吸引人的highlights,而後介紹新版本的新內容,最後介紹deprecated / removed,提醒你們升級時須要注意什麼,條理很清晰。json
安裝
到2020年10月9日爲止,anaconda上尚未任何channel支持對python 3.9的直接安裝,因此想嚐鮮,有2種方法:性能優化
1.到http://python.org上下載安裝包app
2.到anaconda的conda-forge channel下載安裝文件工具
咱們使用第二種方法,安裝文件下載連接見 References。oop
$ conda create -n py39 -c conda-forge -y $ conda activate py39 $ conda install python-3.9.0-h60c2a47_1_cpython.tar.bz2 $ which python /d/Anaconda3/envs/py39/python $ python -V Python 3.9.0
Release Highlights
Python 3.9 內容包括:性能
- 3個新的語法特性
- 1個新的內置特性
- 2個新的標準庫特性
- 6點解釋器提高
- 2個新的庫模塊
若是把以上全部內容都過一遍,可能須要1-2小時。咱們這裏就挑一些與咱們部門產品開發相關的內容,具體來說一講,其它內容若是有興趣,能夠自行去讀讀。優化
New Features
Dictionary Merge & Update Operators
dict類提供了merge (|) 和 update (|=) 操做符。ui
# py38 >>> x = {"key1": "value1 from x", "key2": "value2 from x"} >>> y = {"key2": "value2 from y", "key3": "value3 from y"} >>> {**x, **y} {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'} >>> x.update(y) >>> x {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'} # py39 >>> x = {"key1": "value1 from x", "key2": "value2 from x"} >>> y = {"key2": "value2 from y", "key3": "value3 from y"} >>> x | y {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'} >>> y | x {'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}
這在dict操做時,會更方便。
New string methods to remove prefixes and suffixes
>>> "NavyXie".removeprefix("Navy") 'Xie' >>> "NavyXie".removesuffix("Xie") 'Navy'
這在string刪除不須要的prefix 或 suffix時,會更方便。
Type hinting generics in standard collections
在type annotation中,可使用內置的collection類型,如list和dict,而不用導入相應的大寫類型,如 typing.List 或 typing.Dict。
def greet_all(names: list[str]) -> None: for name in names: print("Hello", name)
Annotation是python 3.0 引入的特徵,是作什麼用的呢?與Java / C / C++ / Swift等強類型語言不一樣,Python和JavaScript都是弱類型語言,這裏類型annotation並不會在解析或運行時強制要求傳參的類型,而只是幫助開發者的代碼閱讀和維護。
另外,若是咱們使用python 3.7引入的庫,dataclasses,時,就會發現,type annotation在定義一個data類時,是強制要求的,好比:
>>> from dataclasses import dataclass >>> @dataclass ... def TestClass: ... name: str ... >>> TestClass.__annotations__ {'name': <class 'str'>}
這個時候就會比較有用,咱們能夠這樣寫:
names: list[str]
而不用像以前那樣:
names: List[str]
新的解析器
Python 3.9 開始使用新的解析器,基於 PEG,而取代LL(1)。二者的性能相差不大,但PEG更靈活。從這裏咱們能夠推斷,從Python 3.10開始,將會引入更多新的語言特性。
zoneinfo
這個新模塊,在咱們操做時區時,會比較方便。以前咱們處理timezone時,須要經過pytz包,好比:
# py38 import pytz from datetime import datetime tz = pytz.timezone("America/Los_Angeles") start_time = datetime.now(tz)
如今能夠經過標準庫中的zoneinfo模塊,好比:
from zoneinfo import ZoneInfo tz = ZoneInfo("America/Los_Angeles")
其它變化
在python 3.8中,Vectorcall協議被臨時引入,3.9中,對內置類型,包括,range, tuple, set, frozenset, list, dict,都使用vectorcall協議進行了優化。但有趣的是,從性能優化報告中,咱們能夠看到,從3.8到3.9的性能並無什麼提高,甚至有小幅降低。
Python version 3.4 3.5 3.6 3.7 3.8 3.9 -------------- --- --- --- --- --- --- Variable and attribute read access: read_local 7.1 7.1 5.4 5.1 3.9 4.0 read_nonlocal 7.1 8.1 5.8 5.4 4.4 4.8 read_global 15.5 19.0 14.3 13.6 7.6 7.7 read_builtin 21.1 21.6 18.5 19.0 7.5 7.7 read_classvar_from_class 25.6 26.5 20.7 19.5 18.4 18.6 read_classvar_from_instance 22.8 23.5 18.8 17.1 16.4 20.1 read_instancevar 32.4 33.1 28.0 26.3 25.4 27.7 read_instancevar_slots 27.8 31.3 20.8 20.8 20.2 24.5 read_namedtuple 73.8 57.5 45.0 46.8 18.4 23.2 read_boundmethod 37.6 37.9 29.6 26.9 27.7 45.9 Variable and attribute write access: write_local 8.7 9.3 5.5 5.3 4.3 4.2 write_nonlocal 10.5 11.1 5.6 5.5 4.7 4.9 write_global 19.7 21.2 18.0 18.0 15.8 17.2 write_classvar 92.9 96.0 104.6 102.1 39.2 43.2 write_instancevar 44.6 45.8 40.0 38.9 35.5 40.7 write_instancevar_slots 35.6 36.1 27.3 26.6 25.7 27.7 Data structure read access: read_list 24.2 24.5 20.8 20.8 19.0 21.1 read_deque 24.7 25.5 20.2 20.6 19.8 21.6 read_dict 24.3 25.7 22.3 23.0 21.0 22.5 read_strdict 22.6 24.3 19.5 21.2 18.9 21.6 Data structure write access: write_list 27.1 28.5 22.5 21.6 20.0 21.6 write_deque 28.7 30.1 22.7 21.8 23.5 23.2 write_dict 31.4 33.3 29.3 29.2 24.7 27.8 write_strdict 28.4 29.9 27.5 25.2 23.1 29.8 Stack (or queue) operations: list_append_pop 93.4 112.7 75.4 74.2 50.8 53.9 deque_append_pop 43.5 57.0 49.4 49.2 42.5 45.5 deque_append_popleft 43.7 57.3 49.7 49.7 42.8 45.5 Timing loop: loop_overhead 0.5 0.6 0.4 0.3 0.3 0.3
備註:以上結果是python 官方 benchmark, Tools/scripts/var_access_benchmark.py, 的運行結果,單位爲納秒,硬件爲Intel® Core™ i7-4960HQ 處理器,OS爲macOS 64-bit。
注意 Deprecated / Removed
我提取了一些與咱們部門產品可能相關度比較高的幾點:
(1)Python 3.9 是提供 Python 2向後兼容的最後一個版本,因此在下個版本 Python 3.10 將不在兼容 Python 2。
(2)threading.Thread類的 isAlive() 方法被刪除,用is_alive()取代。
(3)base64.encodestring() 和 base64.decodestring() 被刪除,用base64.encodebytes() 和 base64.decodebytes() 取代。
(4)json.loads()的encoding參數被刪除,encoding必須爲UTF-8, UTF-16或UTF-32.
複習 Python 3.8 的幾點特性
最後,咱們再複習下 python 3.8 的幾點新特性,若是工做中沒有嘗試過,那就立刻試試吧。
- 海象操做符 :=
if (n := len(a)) > 10: print(f"List is too long ({n} elements, expected <= 10)")
- Positional-only 參數
def f(a, b, /, c, d, *, e, f): print(a, b, c, d, e, f)
- f-string支持 =
>>> user = 'eric_idle' >>> member_since = date(1975, 7, 31) >>> f'{user=} {member_since=}' "user='eric_idle' member_since=datetime.date(1975, 7, 31)" >>> delta = date.today() - member_since >>> f'{user=!s} {delta.days=:,d}' 'user=eric_idle delta.days=16,075' >>> print(f'{theta=} {cos(radians(theta))=:.3f}') theta=30 cos(radians(theta))=0.866
References
-
What’s new in python 3.9, https://docs.python.org/3/whatsnew/3.9.html
-
What’s new in python 3.8, https://docs.python.org/3/whatsnew/3.8.html
-
Conda-forge python files, https://anaconda.org/conda-forge/python/files
-
Python 3.9 tar, https://anaconda.org/conda-forge/python/3.9.0/download/win-64/python-3.9.0-h60c2a47_1_cpython.tar.bz2