Python 3.9,就這?

1.字典合并與更新運算符
在Python3.9以前,你可能需要這樣合并字典:
d1 = {'name': 'revotu', 'age': 99}
d2 = {'age': 24, 'sex': 'male'}
# 方法1,使用兩次update方法向字典中添加元素
d = {}
d.update(d1)
d.update(d2)
print(d)
# 方法2,先復制,后更新,缺點是增加了一個臨時變量
d = d1.copy()
d.update(d2)
print(d)
# 方法3,字典構造器
d = dict(d1)
d.update(d2)
print(d)
# 方法4,關鍵字參數(shù)hack
# 只有一行代碼,看上去很酷,缺點是這種hack技巧只有在字典的鍵是字符串時才有效。
d = dict(d1, **d2)
print(d)
# 方法5,字典拆分,在Python3.5+中,可以使用一種全新的字典合并方式,這行代碼很pythonic
d = {**d1, **d2}
print(d)現(xiàn)在,Python 3.9之后,合并 ( | ) 與更新 ( |= ) 運算符已被加入內(nèi)置的?dict?類。它們?yōu)楝F(xiàn)有的?dict.update?和?{**d1,?**d2}?字典合并方法提供了補充。
>>> 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'}2.新增用于移除前綴和后綴的字符串方法
增加了??和??用于方便地從字符串移除不需要的前綴或后綴。也增加了?bytes,?bytearray??以及?collections.UserString?的對應方法。
內(nèi)置的str類將獲得兩個新方法,它們的源代碼如下:
def?removeprefix(self: str, prefix: str, /)?-> str:
????if?self.startswith(prefix):
????????return?self[len(prefix):]
????else:
????????return?self[:]
def?removesuffix(self: str, suffix: str, /)?-> str:
????# suffix='' should not call self[:-0].
????if?suffix and?self.endswith(suffix):
????????return?self[:-len(suffix)]
????else:
????????return?self[:]它的使用方法如下:
>>?"HelloWorld".removesuffix("World")
'Hello'
>>?"HelloWorld".removeprefix("Hello")
'World'3.類型標注支持更多通用類型
在類型標注中現(xiàn)在你可以使用內(nèi)置多項集類型例如 list 和 dict 作為通用類型而不必從 typing 導入對應的大寫形式類型名 (例如 List 和 Dict)。
比如:
def?greet_all(names: list[str])?-> None:
????for?name in?names:
????????print("Hello", name)4.標準庫新增 zoneinfo 模塊
zoneinfo?模塊為標準庫引入了 IANA 時區(qū)數(shù)據(jù)庫。它添加了?zoneinfo.ZoneInfo,這是一個基于系統(tǒng)時區(qū)數(shù)據(jù)的實體?datetime.tzinfo?實現(xiàn)。
>>> from?zoneinfo import?ZoneInfo
>>> from?datetime import?datetime, timedelta
>>> # 夏時制 - 07:00
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31?12:00:00-07:00
>>> dt.tzname()
'PDT'
>>> # 加7天,夏時制結束 - 08:00
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07?12:00:00-08:00
>>> print(dt.tzname())
PST5.標準庫新增 graphlib 模塊
支持針對圖的操作,比如獲取拓撲排序:

>>> from?graphlib import?TopologicalSorter
>>> graph = {"D": {"B", "C"}, "C": {"A"}, "B": {"A"}}
>>> ts = TopologicalSorter(graph)
>>> tuple(ts.static_order())
('A', 'C', 'B', 'D')關于graphlib模塊更多信息可見:
https://docs.python.org/zh-cn/3/library/graphlib.html#module-graphlib
6.Math模塊迎來調(diào)整
以前gcd計算最大公因數(shù)的函數(shù)只能應用于2個數(shù)字,這就很蛋疼,我們必須使用?math.gcd(80, math.gcd(64, 152))來處理大于2個數(shù)字的情況。而現(xiàn)在 gcd 允許計算任意數(shù)量的數(shù)字:
import?math
# Greatest common divisor
math.gcd(80, 64, 152)
# 8并新增了一個函數(shù),計算最小公倍數(shù):
# 最小公倍數(shù)
math.lcm(4, 8, 5)
# 40
用法與gcd一樣,它允許可變數(shù)量的參數(shù)。
7.os模塊
以前Windows系統(tǒng)下是無法使用 os.unsetenv 的,這個問題在Python3.9已被修復。現(xiàn)在Windows系統(tǒng)也支持?os.unsetenv?了:
def?__init__(self, *args, **kw):
????if?hasattr(os, 'unsetenv'):
????????os.unsetenv('_MEIPASS2')
????else:
????????os.putenv('_MEIPASS2', '')8.random模塊: 新增隨機字節(jié)串
現(xiàn)在你可以使用random下的randbytes函數(shù)隨機生成字節(jié):
>> from?random import?randbytes
>> randbytes(4)
b'\xf3\xf5\xf8\x98'9.性能優(yōu)化
重點優(yōu)化:
1.多個 Python 內(nèi)置類型 (range, tuple, set, frozenset, list, dict) 現(xiàn)在通過使用 PEP 590?向量調(diào)用協(xié)議得到加速。
2.優(yōu)化了在推導式中為臨時變量賦值的慣用方式。現(xiàn)在推導式中的?for?y?in?[expr]?會與簡單賦值語句?y?=?expr?一樣快速。例如:
sums = [s for?s in?[0] for?x in?data for?s in?[s + x]]
不同于?:=?運算符,這個慣用方式不會使變量泄露到外部作用域中。
3.優(yōu)化了多線程應用的信號處理。如果一個線程不是獲得信號的主線程,字節(jié)碼求值循環(huán)不會在每條字節(jié)碼指令上被打斷以檢查無法被處理的掛起信號。只有主解釋器的主線程能夠處理信號。
以下是對從 Python 3.4 到 Python 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????3.9
????read_nonlocal????????????????????7.1?????8.1?????5.8?????5.4?????4.4????4.5
????read_global?????????????????????15.5????19.0????14.3????13.6?????7.6????7.8
????read_builtin????????????????????21.1????21.6????18.5????19.0?????7.5????7.8
????read_classvar_from_class????????25.6????26.5????20.7????19.5????18.4???17.9
????read_classvar_from_instance?????22.8????23.5????18.8????17.1????16.4???16.9
????read_instancevar????????????????32.4????33.1????28.0????26.3????25.4???25.3
????read_instancevar_slots??????????27.8????31.3????20.8????20.8????20.2???20.5
????read_namedtuple?????????????????73.8????57.5????45.0????46.8????18.4???18.7
????read_boundmethod????????????????37.6????37.9????29.6????26.9????27.7???41.1
Variable?and?attribute?write?access:
????write_local??????????????????????8.7?????9.3?????5.5?????5.3?????4.3????4.3
????write_nonlocal??????????????????10.5????11.1?????5.6?????5.5?????4.7????4.8
????write_global????????????????????19.7????21.2????18.0????18.0????15.8???16.7
????write_classvar??????????????????92.9????96.0???104.6???102.1????39.2???39.8
????write_instancevar???????????????44.6????45.8????40.0????38.9????35.5???37.4
????write_instancevar_slots?????????35.6????36.1????27.3????26.6????25.7???25.8
Data?structure?read?access:
????read_list???????????????????????24.2????24.5????20.8????20.8????19.0???19.5
????read_deque??????????????????????24.7????25.5????20.2????20.6????19.8???20.2
????read_dict???????????????????????24.3????25.7????22.3????23.0????21.0???22.4
????read_strdict????????????????????22.6????24.3????19.5????21.2????18.9???21.5
Data?structure?write?access:
????write_list??????????????????????27.1????28.5????22.5????21.6????20.0???20.0
????write_deque?????????????????????28.7????30.1????22.7????21.8????23.5???21.7
????write_dict??????????????????????31.4????33.3????29.3????29.2????24.7???25.4
????write_strdict???????????????????28.4????29.9????27.5????25.2????23.1???24.5
Stack?(or?queue) operations:
????list_append_pop?????????????????93.4???112.7????75.4????74.2????50.8???50.6
????deque_append_pop????????????????43.5????57.0????49.4????49.2????42.5???44.2
????deque_append_popleft????????????43.7????57.3????49.7????49.7????42.8???46.4
Timing?loop:
????loop_overhead????????????????????0.5?????0.6?????0.4?????0.3?????0.3????0.3可以看到,Python 3.9 相比于 Python 3.6 提升還是非常明顯的,比如在列表的append 和 pop 操作上,性能提升了30%、在全局變量的讀取上,性能提高了45%。
如果你的項目比較小型,升級到Python3.9的成本問題和依賴問題不多,還是非常推薦升級的。
10.未來可期
這一個更改你可能看不見、摸不著,但它可能改變Python的未來。
以前Python使用 LL(1) 解析器,從Python 3.9 開始,將使用 PEG 解析器,官方認為,PEG 在設計新語言特性時的形式化比 LL(1) 更靈活。
因此,請期待Python 3.10,Python團隊或許能給我們帶來更多的驚喜!
我們的文章到此就結束啦,如果你喜歡今天的Python 教程,請持續(xù)關注Python實用寶典。

推薦閱讀
歡迎長按掃碼關注「數(shù)據(jù)管道」
