Python3.9 的那些新特性
Python 3.9 已經(jīng)發(fā)布,并開發(fā)了一些新特性,包括字典合并與更新、新的解析器、新的字符串函數(shù)等。
"""
Python 3.9 已于 10 月 5 日發(fā)布,新版本的特性,你 get 到了嗎?對于 Python 程序員來說,這又是一個令人興奮的時刻。
相比于之前的版本,Python 3.9 有哪些值得討論的功能呢?
簡而言之,從字典更新/合并到添加新的字符串方法,Python 3.9 添加了許多新特性。此外,Python 3.9 版本還引入了一種穩(wěn)定、高性能的新型解析器。
"""
現(xiàn)在讓我們一起探索 Python 3.9 的新特性。
Python 3.9:10 個有趣的新特性
1. 字典更新和合并
字典添加兩個新的運(yùn)算符:|和|=。|運(yùn)算符用于合并字典,|= 運(yùn)算符用于更新字典。
字典合并:
>>> a = {‘farhad’: 1, 'blog’: 2,'python’: 3}
>>> b = {’farhad’: 'malik’,'topic’: 'python3.9’}
>>> a | b
{’blog’: 2, 'python’: 3, ’farhad’:’malik’,'topic’: 'python3.9’}
>>> b | a
{’farhad’: 1,’blog’: 2, 'python’: 3,'topic’:’python3.9’ }
字典更新:
>>> a |= b
>>> a
{’blog’: 2, 'python’: 3,’farhad’:’malik’}
2. 新型字符串函數(shù):刪除前綴和后綴
Python 3.9 將兩個新函數(shù)添加到 str 對象:
第一個函數(shù)用于刪除前綴:str.removeprefix(prefix)
第二個函數(shù)用于刪除后綴:str.removesuffix(suffix)
'farhad_python'.removeprefix('farhad_')
# returns python
'farhad_python'.removesuffix('_python')
# returns farhad
3. 統(tǒng)一的軟件包導(dǎo)入錯誤
這與其說是一個特性,不如說是一個修復(fù)。當(dāng)以前的Python導(dǎo)入版本出現(xiàn)不一致時,它的早期導(dǎo)入版本出現(xiàn)了 不一致的錯誤。
"""
builtins.__import__() 引發(fā) ValueError
importlib.__import__() 引發(fā) ImportError
"""
__import__()現(xiàn)在引發(fā)ImportError而不是ValueError,這更有意義。
4. concurrent.futures 優(yōu)化
concurrent.futures.Executor.shutdown() 中添加了一個新參數(shù) cancel_futures。此參數(shù)可以取消尚未執(zhí)行的并發(fā)任務(wù)。在 Python 3.9 之前主進(jìn)程只有在所有并發(fā)任務(wù)完成后才能關(guān)閉 executor 對象。
新參數(shù) cancel_futures 已被添加到 ThreadPoolExecutor 以及 ProcessPoolExecutor。它的工作方式是:當(dāng)參數(shù)的值為 True 時,在調(diào)用 shutdown() 函數(shù)時取消所有待處理的任務(wù)。
5.隨機(jī)字節(jié)生成
random模塊中引入了一個名為randbytes的新方法來生成隨機(jī)字節(jié)。Python已經(jīng)可以通過3個不同的函數(shù)生成隨機(jī)字節(jié),但它們不能產(chǎn)生偽隨機(jī)模式。
os.getrandom() os.urandom() secrets.token_bytes()
這個random.random.randbytes函數(shù)可以以受控的方式生成隨機(jī)字節(jié),并且可以通過設(shè)置種子復(fù)制結(jié)果。不過,它只能在安全性不重要的情況下使用。
6. zoneinfo時區(qū)模塊
zoneinfo是python3.9新引入的模塊,zoneinfo可以訪問Internet號碼分配機(jī)構(gòu)(IANA)時區(qū)數(shù)據(jù)庫。IANA每年都會多次更新其數(shù)據(jù)庫,這是時區(qū)信息的最權(quán)威來源。
使用zoneinfo,可以獲得數(shù)據(jù)庫中描述任何時區(qū)的對象:
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta
>>> # 夏令時
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'
>>> # 標(biāo)準(zhǔn)時間
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07 12:00:00-08:00
>>> print(dt.tzname())
PST
7. 最小公倍數(shù)(LCM)
Python長期以來一直具有用于計算兩個數(shù)字的最大公約數(shù)(GCD)的功能:
>>> import math
>>> math.gcd(49, 14)
7
最小公倍數(shù)(LCM)與最大公約數(shù)(GCD)有關(guān),可以根據(jù)GCD定義LCM:
>>> def lcm(num1, num2):
... if num1 == num2 == 0:
... return 0
... return num1 * num2 // math.gcd(num1, num2)
...
>>> lcm(49, 14)
98
在Python 3.9中,不再需要定義自己的LCM函數(shù),它新增了計算最小公倍數(shù)功能:
>>> import math
>>> math.lcm(49, 14)
98
8. 更強(qiáng)大的Python解析器
Python 3.9最酷的功能之一是大家在日常編程中不會注意到的功能,那就是解析器的更新。解析器是Python解釋器的基本組件。在最新版本中,解析器已重新構(gòu)建。
Python之前一直使用LL(1)解析器將源代碼解析為解析樹。你可以將LL(1)解析器視為一次讀取一個字符,并解釋源代碼而無需回溯的解析器。
新解釋器是基于PEG(parsing expression grammar)實現(xiàn)的,并非LL(1)。新解析器的性能可以與舊解析器媲美,在設(shè)計新語言功能時,PEG比LL(1)更靈活。
在整個標(biāo)準(zhǔn)庫中,PEG解析器稍快一些,然而也使用了更多的內(nèi)存。實際上,使用新解析器時,很難能感知到性能的好壞。
9. 拓?fù)渑判?span style="display: none;">
Python 3.9添加了一個新的模塊graphlib,其中包含
graphlib.TopologicalSorter類,以提供執(zhí)行拓?fù)渑判虻墓δ堋?/p>
>>> dependencies = {
... "realpython-reader": {"feedparser", "html2text"},
... "feedparser": {"sgmllib3k"},
... }
...
>>> from graphlib import TopologicalSorter
>>> ts = TopologicalSorter(dependencies)
>>> list(ts.static_order())
['html2text', 'sgmllib3k', 'feedparser', 'realpython-reader']
10. 異步編程和多進(jìn)程優(yōu)化
Python 3.9 對異步編程(asyncio)和多進(jìn)程庫進(jìn)行了優(yōu)化。
由于安全問題的考慮,asyncio.loop.create_datagram_endpoint() 不再支持參數(shù) reuse_address。
新增了 coroutines、shutdown_default_executor() 和 asyncio.to_thread() 。shutdown_default_executor 負(fù)責(zé)關(guān)閉默認(rèn) executor,asyncio.to_thread() 主要用于在一條單獨(dú)的線程中運(yùn)行 IO 密集型函數(shù),以避免事件循環(huán)。
關(guān)于多進(jìn)程庫的改進(jìn),Python 3.9 向 multiprocessing.SimpleQueue 類添加了新方法 close()。
此方法可以顯式地關(guān)閉隊列。這將確保隊列關(guān)閉并且停留時間不會比預(yù)期長。值得注意的是,一旦關(guān)閉隊列,就不能調(diào)用 get()、put() 和 empty() 方法。



