Python 3.9 有什么新變化?
- 發(fā)布版本
3.12.0a0
- 日期
五月 26, 2022
- 編者
?ukasz Langa
本文介紹了 Python 3.9 相比 3.8 的新特性。 Python 3.9 發(fā)布于 2020 年 10 月 5 日。
詳情請參閱 更新日志。
參見(jiàn)
PEP 596 - Python 3.9 發(fā)布計劃
摘要 -- 發(fā)布重點(diǎn)?
新的語(yǔ)法特性:
新的內置特性:
PEP 616,移除前綴和后綴的字符串方法。
標準庫中的新特性:
PEP 593,靈活函數和變量注解;
添加了
os.pidfd_open()
以允許不帶競爭和信號的進(jìn)程管理。
解釋器的改進(jìn):
PEP 573,從 C 擴展類(lèi)型的方法快速訪(fǎng)問(wèn)模塊狀態(tài);
PEP 617,CPython 現在使用基于 PEG 的新解析器;
一些 Python 內置類(lèi)型(range、tuple、set、frozenset、list、dict)現已使用 PEP 590 vectorcall 加速;
垃圾回收不會(huì )因恢復的對象而阻塞;
一些 Python 模塊(
_abc
、audioop
、_bz2
、_codecs
、_contextvars
、_crypt
、_functools
、_json
、_locale
、math
、operator
、resource
、time
、_weakref
)現已使用 PEP 489 中定義的多段初始化;一些標準庫模塊 (
audioop
、ast
、grp
、_hashlib
、pwd
、_posixsubprocess
、random
、select
、struct
、termios
、zlib
) 現已使用 PEP 384 中定義的穩定 ABI。
新的庫模塊:
發(fā)布進(jìn)程的變化:
PEP 602,CPython 采用年度發(fā)布周期。
請檢查代碼中的 DeprecationWarning。?
Python 2.7 支持未終止時(shí),為了實(shí)現向下兼容 Python 2.7,Python 3 保留了許多舊版功能。Python 2 的支持終止后,已經(jīng)移除了一部分向下兼容層,剩余部分很快也會(huì )被移除。這幾年,大部分兼容層都會(huì )觸發(fā) DeprecationWarning
警告。例如,2012 年發(fā)布 Python 3.3 后,用 collections.Mapping
替代 collections.abc.Mapping
就會(huì )觸發(fā) DeprecationWarning
。
請用 -W
default
命令行選項測試應用程序來(lái)查看 DeprecationWarning
和 PendingDeprecationWarning
,甚至可以用 -W
error
將它們視為錯誤。 可以用 警告過(guò)濾器 忽略來(lái)自第三方代碼的警告。
Python 3.9 是最后一個(gè)提供 Python 2 向下兼容層的版本,以給予 Python 項目維護者更多時(shí)間移除 Python 2 支持,添加 Python 3.9 支持。
collections
模塊中 抽象基類(lèi) 的別名,例如 collections.abc.Mapping
的別名 collections.Mapping
會(huì )為向下兼容最后保留一個(gè)發(fā)行版。 這些內容將在 Python 3.10 中移除。
更通俗的說(shuō)法是,請在 Python 開(kāi)發(fā)模式 下運行測試,這樣做有助于讓代碼兼容 Python 的后續版本。
注:一些前期已棄用的內容也將在此 Python 版本中移除。 詳見(jiàn) 移除 一節。
新的特性?
字典合并與更新運算符?
合并 (|
) 與更新 (|=
) 運算符已被加入內置的 dict
類(lèi)。 它們?yōu)楝F有的 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'}
新增用于移除前綴和后綴的字符串方法?
增加了 str.removeprefix(prefix)
和 str.removesuffix(suffix)
用于方便地從字符串移除不需要的前綴或后綴。 也增加了 bytes
, bytearray
以及 collections.UserString
的對應方法。 請參閱 PEP 616 了解詳情。 (由 Dennis Sweeney 在 bpo-39939 中貢獻。)
標準多項集中的類(lèi)型標注泛型?
在類(lèi)型標注中現在你可以使用內置多項集類(lèi)型例如 list
和 dict
作為通用類(lèi)型而不必從 typing
導入對應的大寫(xiě)形式類(lèi)型名 (例如 List
和 Dict
)。 標準庫中的其他一些類(lèi)型現在同樣也是通用的,例如 queue.Queue
。
示例:
def greet_all(names: list[str]) -> None:
for name in names:
print("Hello", name)
詳見(jiàn) PEP 585。(由 Guido van Rossum、Ethan Smith 和 Batuhan Ta?kaya 在 bpo-39481 中貢獻。)
新的解析器?
Python 3.9 使用于基于 PEG 的新解析器替代 LL(1)。 新解析器的性能與舊解析器大致相當,但 PEG 在設計新語(yǔ)言特性時(shí)的形式化比 LL(1) 更靈活。 我們將在 Python 3.10 及之后版本中開(kāi)始使用這種靈活性。
ast
模塊會(huì )使用新解析器并會(huì )生成與舊解析器一致的 AST。
在 Python 3.10 中,舊解析器將被移除,依賴(lài)于它的所有功能也將被移除(主要是 parser
模塊,它早已被棄用)。 只有 在 Python 3.9 中,你可以使用命令行開(kāi)關(guān) (-X oldparser
) 或環(huán)境變量 (PYTHONOLDPARSER=1
) 切換回 LL(1) 解析器。
請參閱 PEP 617 了解詳情。 (由 Guido van Rossum, Pablo Galindo 和 Lysandros Nikolaou 在 bpo-40334 中貢獻。)
其他語(yǔ)言特性修改?
__import__()
現在會(huì )引發(fā)ImportError
而不是ValueError
,后者曾經(jīng)會(huì )在相對導入超出其最高層級包時(shí)發(fā)生。 (由 Ngalim Siregar 在 bpo-37444 中貢獻。)Python 現在會(huì )獲取命令行中指定的腳本文件名 (例如:
python3 script.py
) 的絕對路徑:__main__
模塊的__file__
屬性將是一個(gè)絕對路徑,而不是相對路徑。 現在此路徑在當前目錄通過(guò)os.chdir()
被改變后仍將保持有效。 作為附帶效果,回溯信息也將在此情況下為__main__
模塊幀顯示絕對路徑。 (由 Victor Stinner 在 bpo-20443 中貢獻。)在 Python 開(kāi)發(fā)模式 以及 調試編譯版本 中,現在會(huì )針對字符串編碼和解碼操作檢查 encoding 和 errors 參數。 例如:
open()
,str.encode()
和bytes.decode()
。默認設置下,為保證性能,errors 參數只會(huì )在第一次發(fā)生編碼/解碼錯誤時(shí)被檢查,并且對于空字符串 encoding 參數有時(shí)會(huì )被忽略。 (由 Victor Stinner 在 bpo-37388 中貢獻。)
"".replace("", s, n)
對于所有非零的n
都將返回s
而不是空字符串。 現在此方法會(huì )與"".replace("", s)
保持一致。 對于bytes
和bytearray
對象也有類(lèi)似的修改。 (由 Serhiy Storchaka 在 bpo-28029 中貢獻。)任何有效的表達式現在都可被用作 decorator。 在之前版本中,相關(guān)語(yǔ)法則更為嚴格。 請參閱 PEP 614 了解詳情。 (由 Brandt Bucher 在 bpo-39702 中貢獻。)
改進(jìn)了
typing
模塊的幫助信息。 現在將為所有特殊形式和特殊通用別名 (例如Union
和List
) 顯示文檔字符串。 使用help()
時(shí)傳入通用別名例如List[int]
將顯示對應實(shí)體類(lèi)型 (這里對應的是list
) 的幫助信息。 (由 Serhiy Storchaka 在 bpo-40257 中貢獻。)aclose()
/asend()
/athrow()
的并行運行現在已被禁止,且ag_running
現在會(huì )反映異步生成器的實(shí)際運行狀態(tài)。 (由 Yury Selivanov 在 bpo-30773 中貢獻。)調用
__iter__
方法時(shí)發(fā)生的非預期錯誤不會(huì )再被in
運算符以及operator
的contains()
,indexOf()
和countOf()
中的TypeError
所掩蓋。 (由 Serhiy Storchaka 在 bpo-40824 中貢獻。)未加圓括號的 lambda 表達式不能再作為推導式和生成器表達式的
if
子句的表達式部分。 請參閱 bpo-41848 和 bpo-43755 了解詳情。
新增模塊?
zoneinfo?
zoneinfo
模塊為標準庫引入了 IANA 時(shí)區數據庫。 它添加了 zoneinfo.ZoneInfo
,這是一個(gè)基于系統時(shí)區數據的實(shí)體 datetime.tzinfo
實(shí)現。
示例:
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta
>>> # Daylight saving time
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'
>>> # Standard time
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07 12:00:00-08:00
>>> print(dt.tzname())
PST
作為不包含 IANA 數據庫的平臺的一個(gè)回退數據源,還以第一方軟件包的形式發(fā)布了 tzdata
模塊 -- 通過(guò) PyPI 發(fā)行并由 CPython 核心團隊維護。
參見(jiàn)
- PEP 615 -- 在標準庫中支持 IANA 時(shí)區數據庫
PEP 由 Paul Ganssle 撰寫(xiě)并實(shí)現
graphlib?
添加了新的 graphlib
模塊,其中包含 graphlib.TopologicalSorter
類(lèi)來(lái)提供圖的拓撲排序功能。 (由 Pablo Galindo, Tim Peters 和 Larry Hastings 在 bpo-17005 中貢獻。)
改進(jìn)的模塊?
ast?
將 indent 選項添加到 dump()
,這允許它產(chǎn)生多行縮進(jìn)的輸出。 (由 Serhiy Storchaka 在 bpo-37995 中貢獻。)
添加了 ast.unparse()
作為 ast
模塊中的一個(gè)函數,它可被用來(lái)反解析 ast.AST
對象并產(chǎn)生相應的代碼字符串,當它被解析時(shí)將會(huì )產(chǎn)生一個(gè)等價(jià)的 ast.AST
對象。 (由 Pablo Galindo 和 Batuhan Taskaya 在 bpo-38870 中貢獻。)
為 AST 節點(diǎn)添加了文檔字符串,其中包含 ASDL 簽名,可被用來(lái)構造對應的節點(diǎn)。 (由 Batuhan Taskaya 在 bpo-39638 中貢獻。)
asyncio?
出于重要的安全性考量,asyncio.loop.create_datagram_endpoint()
的 reuse_address 形參不再被支持。 這是由 UDP 中的套接字選項 SO_REUSEADDR
的行為導致的。 更多細節請參閱 loop.create_datagram_endpoint()
的文檔。 (由 Kyle Stanley, Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中貢獻。。)
添加了新的 coroutine shutdown_default_executor()
,它可為等待 ThreadPoolExecutor
結束關(guān)閉的默認執行器安排關(guān)閉日程操作。 此外,asyncio.run()
已被更新以使用新的 coroutine。 (由 Kyle Stanley 在 bpo-34037 中貢獻。)
添加了 asyncio.PidfdChildWatcher
,這是一個(gè) Linux 專(zhuān)屬的子監視器實(shí)現,它負責輪詢(xún)進(jìn)程的文件描述符。 (bpo-38692)
添加了新的 coroutine asyncio.to_thread()
。 它主要被用于在單獨線(xiàn)程中運行 IO 密集型函數以避免阻塞事件循環(huán),實(shí)質(zhì)上就相當于是 run_in_executor()
的高層級版本,可直接接受關(guān)鍵字參數。 (由 Kyle Stanley 和 Yury Selivanov 在 bpo-32309 中貢獻。)
當由于超時(shí)而取消任務(wù)時(shí),asyncio.wait_for()
現在將會(huì )等待直到也在 timeout 值 <= 0 的情況下完成取消。 就像 timeout 值為正數時(shí)一樣。 (由 Elvis Pranskevichus 在 bpo-32751 中貢獻。)
當附帶 ssl.SSLSocket
套接字調用不兼容的方法時(shí) asyncio
現在會(huì )引發(fā) TyperError
。 (由 Ido Michael 在 bpo-37404 中貢獻。)
compileall?
為重復的 .pyc
文件添加了使用硬軟件的可能性: hardlink_dupes 形參以及 --hardlink-dupes 命令行選項。 (由 Lumír 'Frenzy' Balhar 在 bpo-40495 中貢獻。)
新增了一些用于在結果 .pyc
文件中操縱路徑的選項: stripdir, prependdir, limit_sl_dest 形參以及 -s, -p, -e 命令行選項。 并使得為優(yōu)化等級多次指定選項成為可能。 (由 Lumír 'Frenzy' Balhar 在 bpo-38112 中貢獻。)
concurrent.futures?
將新的 cancel_futures 形參添加到 concurrent.futures.Executor.shutdown()
,可以取消尚未開(kāi)始運行的所有掛起的 Future,而不必等待它們完成運行再關(guān)閉執行器。 (由 Kyle Stanley 在 bpo-39349 中貢獻。)
從 ThreadPoolExecutor
和 ProcessPoolExecutor
中移除了守護線(xiàn)程。 這改善與與子解釋器的兼容性及它們在關(guān)閉進(jìn)程時(shí)的可預測性。 (由 Kyle Stanley 在 bpo-39812 中貢獻。)
現在 ProcessPoolExecutor
中的工作進(jìn)程僅會(huì )在沒(méi)有可重用的空閑工作進(jìn)程時(shí)按需產(chǎn)生。 這優(yōu)化了啟動(dòng)開(kāi)銷(xiāo)并減少了由空閑工作進(jìn)程導致的 CPU 時(shí)間損失。 (由 Kyle Stanley 在 bpo-39207 中貢獻。)
curses?
增加了 curses.get_escdelay()
, curses.set_escdelay()
, curses.get_tabsize()
以及 curses.set_tabsize()
函數。(由 Anthony Sottile 在 bpo-38312 中貢獻。)
datetime?
datetime.date
的 isocalendar()
以及 datetime.datetime
的 isocalendar()
等方法現在將返回 namedtuple()
而不是 tuple
。 (由 Dong-hee Na 在 bpo-24416 中貢獻。)
distutils?
upload 命令現在會(huì )創(chuàng )建 SHA2-256 和 Blake2b-256 哈希摘要。 它會(huì )在禁用 MD5 摘要的平臺上跳過(guò) MD5。 (由 Christian Heimes 在 bpo-40698 中貢獻。)
fcntl?
增加了 F_OFD_GETLK
, F_OFD_SETLK
和 F_OFD_SETLKW
等常量。 (由 Dong-hee Na 在 bpo-38602 中貢獻。)
ftplib?
現在 FTP
和 FTP_TLS
當它們的構造器所給定的超時(shí)參數為零以防止創(chuàng )建非阻塞套接字時(shí)會(huì )引發(fā) ValueError
。 (由 Dong-hee Na 在 bpo-39259 中貢獻。)
gc?
當垃圾回收器進(jìn)行某些復活對象的收集時(shí)(在終結器被執行之后這些對象可以在隔離周期之外被訪(fǎng)問(wèn)),不會(huì )阻止對所有仍然無(wú)法訪(fǎng)問(wèn)的對象的收集。 (由 Pablo Galindo 和 Tim Peters 在 bpo-38379 中貢獻。)
增加了一個(gè)新的函數 gc.is_finalized()
用來(lái)檢測一個(gè)對象是否已被垃圾回收器所終結。 (由 Pablo Galindo 在 bpo-39322 中貢獻。)
hashlib?
hashlib
模塊現在會(huì )在可能的情況下使用 OpenSSL 中的 SHA3 哈希和 SHAKE XOF。 (由 Christian Heimes 在 bpo-37630 中貢獻。)
內置的哈希模塊現在可通過(guò) ./configure --without-builtin-hashlib-hashes
禁用或通過(guò) ./configure --with-builtin-hashlib-hashes=sha3,blake2
這樣的形式有選擇地啟用以強制使用基于 OpenSSL 的實(shí)現。 (由 Christian Heimes 在 bpo-40479 中貢獻)
http?
添加 HTTP 狀態(tài)碼 103 EARLY_HINTS
, 418 IM_A_TEAPOT
和 425 TOO_EARLY
到 http.HTTPStatus
。 (由 Dong-hee Na 在 bpo-39509 以及 Ross Rhodes 在 bpo-39507 中貢獻。)
IDLE 與 idlelib?
添加了切換光標閃爍停止的選項。 (由 Zackery Spytz 在 bpo-4603 中貢獻。)
Esc 鍵現在會(huì )關(guān)閉 IDLE 補全提示窗口。 (由 Johnny Najera 在 bpo-38944 中貢獻。)
添加關(guān)鍵字到模塊名稱(chēng)補全列表。 (由 Terry J. Reedy 在 bpo-37765 中貢獻。)
New in 3.9 maintenance releases
Make IDLE invoke sys.excepthook()
(when started without '-n').
User hooks were previously ignored. (Contributed by Ken Hilton in
bpo-43008.)
上述修改已被反向移植到 3.8 維護發(fā)行版中。
Rearrange the settings dialog. Split the General tab into Windows and Shell/Ed tabs. Move help sources, which extend the Help menu, to the Extensions tab. Make space for new options and shorten the dialog. The latter makes the dialog better fit small screens. (Contributed by Terry Jan Reedy in bpo-40468.) Move the indent space setting from the Font tab to the new Windows tab. (Contributed by Mark Roseman and Terry Jan Reedy in bpo-33962.)
Apply syntax highlighting to .pyi files. (Contributed by Alex Waygood and Terry Jan Reedy in bpo-45447.)
imaplib?
現在 IMAP4
和 IMAP4_SSL
的構造器具有可選的 timeout 形參。 并且,現在 open()
方法也具有可選的 timeout 形參提供同樣的修改。 IMAP4_SSL
和 IMAP4_stream
中被重載的方法也應用了這個(gè)修改。 (由 Dong-hee Na 在 bpo-38615 中貢獻。)
增加了 imaplib.IMAP4.unselect()
。 imaplib.IMAP4.unselect()
會(huì )釋放關(guān)聯(lián)到選定郵箱的服務(wù)器資源并將服務(wù)器返回到已認證狀態(tài)。 此命令會(huì )執行與 imaplib.IMAP4.close()
相同的動(dòng)作,區別在于它不會(huì )從當前選定郵箱中永久性地移除消息。 (由 Dong-hee Na 在 bpo-40375 中貢獻。)
importlib?
為提升與 import 語(yǔ)句的一致性,現在 importlib.util.resolve_name()
對于無(wú)效的相對導入嘗試會(huì )引發(fā) ImportError
而不是 ValueError
。 (由 Ngalim Siregar 在 bpo-37444 中貢獻。)
發(fā)布不可變模塊對象的導入加載器除了發(fā)布單獨模塊以外現在也可以發(fā)布不可變包。 (由 Dino Viehland 在 bpo-39336 中貢獻。)
添加了帶有對包數據中子目錄支持的 importlib.resources.files()
函數,與 importlib_resources
1.5 版的反向端口相匹配。(由 Jason R. Coombs 在 bpo-39791 中貢獻。)
來(lái)自 importlib_metadata
1.6.1 版的已更新 importlib.metadata
。
inspect?
inspect.BoundArguments.arguments
已從 OrderedDict
改為常規字典。 (由 Inada Naoki 在 bpo-36350 和 bpo-39775 中貢獻。)
ipaddress?
ipaddress
現在支持 IPv6 作用域地址(即帶有 %<scope_id>
前綴的 IPv6 地址)。
IPv6 作用域地址可使用 ipaddress.IPv6Address
來(lái)解析。 作用域的區 ID 如果存在,可通過(guò) scope_id
屬性來(lái)獲取。 (由 Oleksandr Pavliuk 在 bpo-34788 中貢獻。)
從 Python 3.9.5 開(kāi)始 ipaddress
模塊不再接受 IPv4 地址字符串中有任何前綴的零。 (由 Christian Heimes 在 bpo-36384 中貢獻。)
math?
對 math.gcd()
函數進(jìn)行了擴展以處理多個(gè)參數。 在之前版本中,它只支持兩個(gè)參數。 (由 Serhiy Storchaka 在 bpo-39648 中貢獻。)
增加了 math.lcm()
: 返回指定參數的最小公倍數。 (由 Mark Dickinson, Ananthakrishnan 和 Serhiy Storchaka 在 bpo-39479 和 bpo-39648 中貢獻。)
增加了 math.nextafter()
: 返回從 x 往 y 方向的下一個(gè)浮點(diǎn)數值。 (由 Victor Stinner 在 bpo-39288 中貢獻。)
增加了 math.ulp()
: 返回一個(gè)浮點(diǎn)數的最小有效比特位。 (由 Victor Stinner 在 bpo-39310 中貢獻。)
multiprocessing?
multiprocessing.SimpleQueue
類(lèi)新增了 close()
方法用來(lái)顯式地關(guān)閉隊列。 (由 Victor Stinner 在 bpo-30966 中貢獻。)
nntplib?
現在 NNTP
和 NNTP_SSL
當它們的構造器所給定的超時(shí)參數為零以防止創(chuàng )建非阻塞套接字時(shí)會(huì )引發(fā) ValueError
。 (由 Dong-hee Na 在 bpo-39259 中貢獻。)
os?
增加了 CLD_KILLED
和 CLD_STOPPED
作為 si_code
。 (由 Dong-hee Na 在 bpo-38493 中貢獻。)
對外公開(kāi)了 Linux 專(zhuān)屬的 os.pidfd_open()
(bpo-38692) 和 os.P_PIDFD
(bpo-38713) 用于文件描述符的進(jìn)程管理。
現在 os.unsetenv()
函數在 Windows 上也已可用。 (由 Victor Stinner 在 bpo-39413 中貢獻。)
現在 os.putenv()
和 os.unsetenv()
函數將總是可用。 (由 Victor Stinner 在 bpo-39395 中貢獻。)
增加了 os.waitstatus_to_exitcode()
函數:將等待狀態(tài)轉換為退出碼。 (由 Victor Stinner 在 bpo-40094 中貢獻。)
pathlib?
增加了 pathlib.Path.readlink()
,其行為類(lèi)似于 os.readlink()
。 (由 Girts Folkmanis 在 bpo-30618 中貢獻。)
pdb?
在 Windows 上 Pdb
現在支持 ~/.pdbrc
。 (由 Tim Hopper 和 Dan Lidral-Porter 在 bpo-20523 中貢獻。)
poplib?
現在 POP3
和 POP3_SSL
當它們的構造器所給定的超時(shí)參數為零以防止創(chuàng )建非阻塞套接字時(shí)會(huì )引發(fā) ValueError
。 (由 Dong-hee Na 在 bpo-39259 中貢獻。)
pprint?
現在 pprint
能美化打印 types.SimpleNamespace
。 (由 Carl Bordum Hansen 在 bpo-37376 中貢獻。)
pydoc?
文檔字符串的顯示現在不僅針對類(lèi)、函數、方法等,也針對任何具有自己的 __doc__
屬性的對象。 (由 Serhiy Storchaka 在 bpo-40257 中貢獻。)
random?
增加了新的 random.Random.randbytes
方法:生成隨機字節串。 (由 Victor Stinner 在 bpo-40286 中貢獻。)
signal?
對外公開(kāi)了 Linux 專(zhuān)屬的 signal.pidfd_send_signal()
用于向使用文件描述符而非 pid 的進(jìn)程發(fā)送信號。 (bpo-38712)
smtplib?
現在 SMTP
和 SMTP_SSL
當它們的構造器所給定的超時(shí)參數為零以防止創(chuàng )建非阻塞套接字時(shí)會(huì )引發(fā) ValueError
。 (由 Dong-hee Na 在 bpo-39259 中貢獻。)
現在 LMTP
構造器具有可選的 timeout 形參。 (由 Dong-hee Na 在 bpo-39329 中貢獻。)
socket?
socket
模塊現在會(huì )在 Linux 4.1 或更高版本上導出 CAN_RAW_JOIN_FILTERS
常量。 (由 Stefan Tatschner 和 Zackery Spytz 在 bpo-25780 中貢獻。)
現在 socket 模塊會(huì )在支持的平臺上支持 CAN_J1939
協(xié)議。 (由 Karl Ding 在 bpo-40291 上貢獻。)
現在 socket 模塊具有 socket.send_fds()
和 socket.recv_fds()
函數。 (由 Joannah Nanjekye, Shinya Okano 和 Victor Stinner 在 bpo-28724 中貢獻。)
time?
On AIX, thread_time()
is now implemented with thread_cputime()
which has nanosecond resolution, rather than
clock_gettime(CLOCK_THREAD_CPUTIME_ID)
which has a resolution of 10 milliseconds.
(Contributed by Batuhan Taskaya in bpo-40192)
sys?
增加了新的 sys.platlibdir
屬性:平臺專(zhuān)屬庫目錄的名稱(chēng)。 它被用于構建標準庫的路徑以及已安裝擴展模塊的路徑。 它在大多數平臺上等于 "lib"
。 在 Fedora 和 SuSE 上,它等于 64 位平臺上的 "lib64"
。 (由 Jan Matějek, Matěj Cepl, Charalampos Stratakis 和 Victor Stinner 在 bpo-1294959 中貢獻。)
之前的版本中,sys.stderr
在非交互模式時(shí)是帶塊緩沖的。 現在 stderr
默認總是為行緩沖的。 (由 Jendrik Seipp 在 bpo-13601 中貢獻。)
tracemalloc?
增加了 tracemalloc.reset_peak()
用于將跟蹤的內存塊峰值大小設為當前大小,以測量特定代碼段的峰值。 (由 Huon Wilson 在 bpo-40630 中貢獻。)
typing?
PEP 593 引入了一種 typing.Annotated
類(lèi)型以使用上下文專(zhuān)屬的元數據來(lái)裝飾現有類(lèi)型,并將新的 include_extras
形參添加到 typing.get_type_hints()
以在運行時(shí)訪(fǎng)問(wèn)元數據。 (由 Till Varoquaux 和 Konstantin Kashin 貢獻。)
unicodedata?
Unicode 數據庫已更新到 13.0.0 版。 (bpo-39926)。
venv?
由 venv
所提供的激活腳本現在總是會(huì )使用 __VENV_PROMPT__
設置的值來(lái)一致地指明它們的自定義提示符。 在之前版本中某些腳本會(huì )無(wú)條件地使用 __VENV_PROMPT__
,而另一些腳本只在其恰好被設置時(shí)(這是默認情況)才會(huì )使用,還有的腳本會(huì )改用 __VENV_NAME__
。 (由 Brett Cannon 在 bpo-37663 中貢獻。)
xml?
當把 xml.etree.ElementTree
序列化為 XML 文件時(shí)屬性?xún)炔康目瞻鬃址F在將被保留。 不同的行結束符不會(huì )再被正規化為 "n"。 這是對于如何解讀 XML 規范 2.11 節的相關(guān)討論的最終結果。 (由 Mefistotelis 在 bpo-39011 中貢獻。)
性能優(yōu)化?
優(yōu)化了在推導式中為臨時(shí)變量賦值的慣用方式。 現在推導式中的
for y in [expr]
會(huì )與簡(jiǎn)單賦值語(yǔ)句y = expr
一樣快速。 例如:sums = [s for s in [0] for x in data for s in [s + x]]
不同于
:=
運算符,這個(gè)慣用方式不會(huì )使變量泄露到外部作用域中。(由 Serhiy Storchaka 在 bpo-32856 中貢獻。)
優(yōu)化了多線(xiàn)程應用中的信號處理。 如果一個(gè)線(xiàn)程不是獲得信號的主線(xiàn)程,字節碼求值循環(huán)不會(huì )在每條字節碼指令上被打斷以檢查無(wú)法被處理的掛起信號。 只有主解釋器的主線(xiàn)程能夠處理信號。
在之前版本中,字節碼求值循環(huán)會(huì )在每條指令上被打斷直到主線(xiàn)程處理了信號。 (由 Victor Stinner 在 bpo-40010 上貢獻。)
在 FreeBSD 上使用
closefrom()
優(yōu)化了subprocess
模塊。 (由 Ed Maste, Conrad Meyer, Kyle Evans, Kubilay Kocak 和 Victor Stinner 在 bpo-38061 中貢獻。)PyLong_FromDouble()
對于匹配 long 的值執行速度現在加快了 1.87 倍。 (由 Sergey Fedoseev d bpo-37986 中貢獻。)多個(gè) Python 內置類(lèi)型 (
range
,tuple
,set
,frozenset
,list
,dict
) 現在通過(guò)使用 PEP 590 向量調用協(xié)議得到加速。 (由 Dong-hee Na, Mark Shannon, Jeroen Demeyer 和 Petr Viktorin 在 bpo-37207 中貢獻。)當另一集合遠大于基礎集合的情況下優(yōu)化了
difference_update()
的性能。 (由 Evgeny Kapun 提議,由 Michele Orrù 在 bpo-8425 中貢獻代碼。)Python 的小對象分配器 (
obmalloc.c
) 現在允許(至多)一個(gè)空位可用于立即重用,而不必將其返回給 OS。 這可以防止簡(jiǎn)單循環(huán)中的多余消耗,在每次迭代中可以創(chuàng )建和銷(xiāo)毀全新的空位。 (由 Tim Peters 在 bpo-37257 中貢獻。)浮點(diǎn)數運算中的 floor division 現在會(huì )有更好的性能。 并且此運算的
ZeroDivisionError
的消息也已更新。 (由 Dong-hee Na 在 bpo-39434 中貢獻。)使用 UTF-8 和 ascii 編解碼器解碼短 ASCII 字符串現在會(huì )加快大約 15%。 (由 Inada Naoki 在 bpo-37348 中貢獻。)
以下是對從 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
以上結果是由以下變量訪(fǎng)問(wèn)基準測試腳本所生成的: Tools/scripts/var_access_benchmark.py
。 該基準測試腳本以納秒為單位顯示時(shí)間。 基準測試數據是在一塊 Intel? Core? i7-4960HQ 處理器 運行從 python.org 獲取的 macOS 64 位編譯版本所得到的。
棄用?
distutils 的
bdist_msi
命令現在已被棄用,請改用bdist_wheel
(wheel 包)。 (由 Hugo van Kemenade 在 bpo-39586 中貢獻。)目前
math.factorial()
接受具有非負整數值的float
實(shí)例 (如5.0
)。 對于非整數和負浮點(diǎn)數它會(huì )引發(fā)ValueError
。 此行為現在已被棄用。 在未來(lái)的 Python 版本中對所有浮點(diǎn)數都將引發(fā)TypeError
。 (由 Serhiy Storchaka 在 bpo-37315 中貢獻。)parser
和symbol
模塊已被棄用并將在未來(lái)的 Python 版本中移除。 對于大多數用例,用戶(hù)都可以使用ast
模塊來(lái)控制抽象語(yǔ)法樹(shù) (AST) 的生成和編譯階段。公有 C API 函數
PyParser_SimpleParseStringFlags()
,PyParser_SimpleParseStringFlagsFilename()
,PyParser_SimpleParseFileFlags()
和PyNode_Compile()
已被棄用并將在 Python 3.10 版與舊解析器一起被移除。在布爾運算中使用
NotImplemented
已被棄用,因為它幾乎必定是不正確的富比較運算符實(shí)現的結果。 它將在未來(lái)的 Python 版本中引發(fā)TypeError
。 (由 Josh Rosenberg 在 bpo-35712 中貢獻。)random
模塊目前接受任何可哈希類(lèi)型作為可能的種子值。 不幸的是,某些這樣的類(lèi)型并不保證具有確定性的哈希值。 在 Python 3.9 之后,該模塊將限定其種子值為None
,int
,float
,str
,bytes
以及bytearray
。打開(kāi)
GzipFile
文件用于寫(xiě)入而不指定 mode 參數的特性已被棄用。 在未來(lái)的 Python 版本中將總是默認打開(kāi)用于讀取。 在打開(kāi)文件用于寫(xiě)入時(shí)請指定 mode 參數以靜默相關(guān)警告信息。 (由 Serhiy Storchaka 在 bpo-28286 中貢獻。)棄用了
_tkinter.TkappType
的split()
方法而改用splitlist()
方法,此方法具有更穩定且可預測的行為。 (由 Serhiy Storchaka 在 bpo-38371 中貢獻。)將協(xié)程對象顯式傳遞給
asyncio.wait()
的做法已被棄用并且將在 3.11 版中被移除。 (由 Yury Selivanov 和 Kyle Stanley 在 bpo-34790 中貢獻。)binhex4 和 hexbin4 標準現已被棄用。
binhex
模塊和下列binascii
函數現已被棄用:b2a_hqx()
,a2b_hqx()
rlecode_hqx()
,rledecode_hqx()
(由 Victor Stinner 在 bpo-39353 中貢獻。)
ast
類(lèi)slice
,Index
和ExtSlice
被視為已棄用并將在未來(lái)的 Python 版本中被移除。 應當使用value
本身而不再是Index(value)
。 應當使用Tuple(slices, Load())
而不再是ExtSlice(slices)
。 (由 Serhiy Storchaka 在 bpo-34822 中貢獻。)ast
類(lèi)Suite
,Param
,AugLoad
和AugStore
被視為已棄用并將在未來(lái)的 Python 版本中被移除。 它們不會(huì )被解析器所生成且不會(huì )被 Python 3 中的代碼生成器所接受。 (由 Batuhan Taskaya 在 bpo-39639 和 bpo-39969 中以及 Serhiy Storchaka 在 bpo-39988 中貢獻。)PyEval_InitThreads()
和PyEval_ThreadsInitialized()
函數現已被棄用并將在 Python 3.11 中被移除。 調用PyEval_InitThreads()
現在沒(méi)有任何效果。 自 Python 3.7 起 GIL 會(huì )由Py_Initialize()
初始化。 (由 Victor Stinner 在 bpo-39877 中貢獻。)傳入
None
作為shlex.split()
函數的第一個(gè)參數的做法已被棄用。 (由 Zackery Spytz 在 bpo-33262 中貢獻。)smtpd.MailmanProxy()
現在已被棄用,因為它在沒(méi)有外部模塊mailman
的情況下無(wú)法使用。 (由 Samuel Colvin 在 bpo-35800 中貢獻。)現在
lib2to3
模塊將發(fā)出PendingDeprecationWarning
。 Python 3.9 已切換到 PEG 解析器 (參見(jiàn) PEP 617),Python 3.10 可以會(huì )包含 lib2to3 的 LL(1) 解析器所不能解析的新語(yǔ)法。lib2to3
模塊可能會(huì )在未來(lái)的 Python 版本中被移出標準庫。 請考慮使用第三方替換例如 LibCST 或 parso。 (由 Carl Meyer 在 bpo-40360 中貢獻。)random.shuffle()
的 random 形參已被棄用。 (由 Raymond Hettinger 在 bpo-40465 中貢獻。)
移除?
unittest.mock.__version__
上的錯誤版本已經(jīng)被移除。nntplib.NNTP
:xpath()
和xgtitle()
方法已被移除。 這些方法自 Python 3.3 起已被棄用。 一般來(lái)說(shuō),這些擴展都不再為 NNTP 服務(wù)管理員所支持或啟用。 對于xgtitle()
,請改用nntplib.NNTP.descriptions()
或nntplib.NNTP.description()
。 (由 Dong-hee Na 在 bpo-39366 中貢獻。)array.array
:tostring()
和fromstring()
方法已被移除。 它們分別是tobytes()
和frombytes()
的別名,自 Python 3.2 起已被棄用。 (由 Victor Stinner 在 bpo-38916 中貢獻。)未寫(xiě)入文檔的
sys.callstats()
函數已被移除。 自 Python 3.7 起它就已被棄用并且總是會(huì )返回None
。 它需要一個(gè)特殊的構建選項CALL_PROFILE
而該選項在 Python 3.7 中已被移除。 (由 Victor Stinner 在 bpo-37414 中貢獻。)sys.getcheckinterval()
和sys.setcheckinterval()
函數已被移除。 它們自 Python 3.2 起已被棄用。 請改用sys.getswitchinterval()
和sys.setswitchinterval()
。 (由 Victor Stinner 在 bpo-37392 中貢獻。)C 函數
PyImport_Cleanup()
已被移除。 它原本的文檔為: "清空模塊表。 僅限內部使用。" (由 Victor Stinner 在 bpo-36710 中貢獻。)_dummy_thread
和dummy_threading
模塊已被移除。 這些模塊自 Python 3.7 起已被棄用,它們需要線(xiàn)程支持。 (由 Victor Stinner 在 bpo-37312 中貢獻。)aifc.open()
的別名aifc.openfp()
,sunau.open()
的別名sunau.openfp()
,以及wave.open()
的別名wave.openfp()
已被移除。 它們自 Python 3.7 起已被棄用。 (由 Victor Stinner 在 bpo-37320 中貢獻。)threading.Thread
的isAlive()
方法已被移除。 它自 Python 3.8 起已被棄用。 請改用is_alive()
。 (由 Dong-hee Na 在 bpo-37804 中貢獻。)ElementTree
模塊中ElementTree
和Element
等類(lèi)的getchildren()
和getiterator()
方法已被移除。 它們在 Python 3.2 中已被棄用。 請使用iter(x)
或list(x)
替代x.getchildren()
并用x.iter()
或list(x.iter())
替代x.getiterator()
。 (由 Serhiy Storchaka 在 bpo-36543 中貢獻。)舊的
plistlib
API 已被移除,它自 Python 3.4 起已被棄用。 請使用load()
,loads()
,dump()
和dumps()
等函數。 此外,use_builtin_types 形參已被移除而總是會(huì )使用bytes
對象。 (由 Jon Janzen 在 bpo-36409 中貢獻。)C 函數
PyGen_NeedsFinalizing
已被移除。 它未被寫(xiě)入文檔、未經(jīng)測試,且自 PEP 442 實(shí)現之后未在 CPython 的任何地方被使用。 由 Joannah Nanjekye 提供補丁。 (由 Joannah Nanjekye 在 bpo-15088 中貢獻。)自 Python 3.1 起被棄用的別名
base64.encodestring()
和base64.decodestring()
已被移除:請改用base64.encodebytes()
和base64.decodebytes()
。 (由 Victor Stinner 在 bpo-39351 中貢獻。)fractions.gcd()
函數已被移除,它自 Python 3.5 起被棄用 (bpo-22486):請改用math.gcd()
。 (由 Victor Stinner 在 bpo-39350 中貢獻。)bz2.BZ2File
的 buffering 形參已被移除。 它自 Python 3.0 起即被忽略,使用它將會(huì )引發(fā)DeprecationWarning
。 請傳入一個(gè)打開(kāi)文件對象來(lái)控制文件的打開(kāi)方式。 (由 Victor Stinner 在 bpo-39357 中貢獻。)json.loads()
的 encoding 形參已被移除。 它在 Python 3.1 中已被棄用和忽略;自 Python 3.8 起使用它將會(huì )引發(fā)DeprecationWarning
。 (由 Inada Naoki 在 bpo-39377 中貢獻。)with (await asyncio.lock):
和with (yield from asyncio.lock):
語(yǔ)句已不再受支持,請改用async with lock
。asyncio.Condition
和asyncio.Semaphore
也同樣如此。 (由 Andrew Svetlov 在 bpo-34793 中貢獻。)sys.getcounts()
函數,-X showalloccount
命令行選項以及 C 結構體PyConfig
的show_alloc_count
字段已被移除。 它們需要使用定義了COUNT_ALLOCS
宏的特殊 Python 編譯版本。 (由 Victor Stinner 在 bpo-39489 中貢獻。)typing.NamedTuple
類(lèi)的_field_types
屬性已被移除。 它自 Python 3.8 起已被棄用。 請改用__annotations__
屬性。 (由 Serhiy Storchaka 在 bpo-40182 中貢獻。)symtable.SymbolTable.has_exec()
方法已被移除。 它自 2006 年起已被棄用,當被調用時(shí)僅會(huì )返回False
。 (由 Batuhan Taskaya 在 bpo-40208 中貢獻。)asyncio.Task.current_task()
和asyncio.Task.all_tasks()
已被移除。 它們自 Python 3.7 起已被棄用,你可以改用asyncio.current_task()
和asyncio.all_tasks()
。 (由 Rémi Lapeyre 在 bpo-40967 中貢獻。)html.parser.HTMLParser
類(lèi)的unescape()
方法已被移除(它自 Python 3.4 起已被棄用)。 應當使用html.unescape()
來(lái)將字符引用轉換為對應的 unicode 字符。
移植到 Python 3.9?
本節列出了先前描述的更改以及可能需要更改代碼的其他錯誤修正.
Python API 的變化?
__import__()
和importlib.util.resolve_name()
現在會(huì )引發(fā)ImportError
取代之前所引發(fā)的ValueError
。 捕獲特定異常類(lèi)型并同時(shí)支持 Python 3.9 和更早版本的調用者將需要使用except (ImportError, ValueError):
來(lái)同時(shí)捕獲兩者。venv
激活腳本不再將__VENV_PROMPT__
被設為""
的情況作為特例處理。select.epoll.unregister()
方法不會(huì )再忽略EBADF
錯誤。 (由 Victor Stinner 在 bpo-39239 中貢獻。)bz2.BZ2File
的 compresslevel 形參已成為僅限關(guān)鍵字形參,因為 buffering 形參已被移除。 (由 Victor Stinner 在 bpo-39357 中貢獻。)簡(jiǎn)化了 AST 的抽取操作。 簡(jiǎn)單索引將以它們的值來(lái)代表,擴展切片將以元組形式來(lái)代表。
Index(value)
將返回value
本身,ExtSlice(slices)
將返回Tuple(slices, Load())
。 (由 Serhiy Storchaka 在 bpo-34822 中貢獻。)當使用了
-E
或-I
命令行參數時(shí)importlib
模塊現在會(huì )忽略PYTHONCASEOK
環(huán)境變量。encoding 形參已作為僅限關(guān)鍵字形參被添加到
ftplib.FTP
和ftplib.FTP_TLS
類(lèi),并且默認編碼格式由 Latin-1 改為 UTF-8 以遵循 RFC 2640。asyncio.loop.shutdown_default_executor()
已被添加到AbstractEventLoop
,這意味著(zhù)繼承自它的替代事件循環(huán)應當定義此方法。 (由 Kyle Stanley 在 bpo-34037 中貢獻。)更新了
__future__
模塊中未來(lái)特性旗標的常量值以防止與編譯器旗標相沖突。 在之前版本中PyCF_ALLOW_TOP_LEVEL_AWAIT
會(huì )與CO_FUTURE_DIVISION
發(fā)生沖突。 (由 Batuhan Taskaya 在 bpo-39562 中貢獻。)array('u')
現在使用wchar_t
作為 C 類(lèi)型而不是Py_UNICODE
。 這個(gè)改變不會(huì )影響其行為,因為自 Python 3.3 起Py_UNICODE
是wchar_t
的別名。 (由 Inada Naoki 在 bpo-34538 中貢獻。)現在
logging.getLogger()
API 當傳入名稱(chēng)'root'
時(shí)將返回根日志記錄器,而在之前它則返回一個(gè)名為'root'
的非根日志記錄器。 這可能會(huì )影響到用戶(hù)代碼明確希望使用一個(gè)名為'root'
的非根日志記錄器,或在某個(gè)名為'root.py'
的最高層級模塊中使用logging.getLogger(__name__)
來(lái)實(shí)例化日志記錄器的情況。 (由 Vinay Sajip 在 bpo-37742 中貢獻。)現在
PurePath
的拆分處理當傳入str
或PurePath
的實(shí)例以外的對象時(shí)會(huì )返回NotImplemented
而不是引發(fā)TypeError
。 這將允許創(chuàng )建不繼承自上述類(lèi)型的兼容類(lèi)。 (由 Roger Aiudi 在 bpo-34775 中貢獻。)從 Python 3.9.5 開(kāi)始
ipaddress
模塊不再接受 IPv4 地址字符串中有任何前綴的零。 前綴的零有歧義且會(huì )被某些庫解讀為八進(jìn)制數字。 例如舊版函數socket.inet_aton()
就瘵前綴的零視為八進(jìn)制數字。 最新inet_pton()
的 glibc 實(shí)現則不接受任何前綴的零。 (由 Christian Heimes 在 bpo-36384 中貢獻)。codecs.lookup()
現在會(huì )以與encodings.normalize_encoding()
相同的方式正規化編碼格式名稱(chēng),不同之處在于codecs.lookup()
還會(huì )將名稱(chēng)轉換為小寫(xiě)形式。 例如``"latex+latin1"`` 編寫(xiě)格式名稱(chēng)現在會(huì )被正規化為"latex_latin1"
。 (由 Jordon Xu 在 bpo-37751 中貢獻。)
C API 的變化?
Instances of 堆分配類(lèi)型 的實(shí)例(例如使用
PyType_FromSpec()
和類(lèi)似 API 創(chuàng )建的實(shí)例)自 Python 3.8 起會(huì )帶有一個(gè)對其類(lèi)型對象的引用。 正如 Python 3.8 的 "C API 的變化" 部分所述,對于大多數情況來(lái)說(shuō),這應當不會(huì )有任何副作用,但對于具有自定義tp_traverse
函數的類(lèi)型來(lái)說(shuō),則要確保所有堆分配類(lèi)型的自定義tp_traverse
函數可訪(fǎng)問(wèn)對象的類(lèi)型。示例:
int foo_traverse(foo_struct *self, visitproc visit, void *arg) { // Rest of the traverse function #if PY_VERSION_HEX >= 0x03090000 // This was not needed before Python 3.9 (Python issue 35810 and 40217) Py_VISIT(Py_TYPE(self)); #endif }
如果你的遍歷函數委托給了其基類(lèi)(或其他類(lèi))的
tp_traverse
,則要確保Py_TYPE(self)
只被訪(fǎng)問(wèn)一次。 請注意應當只有 堆類(lèi)型 可訪(fǎng)問(wèn)tp_traverse
中的類(lèi)型。舉例來(lái)說(shuō),如果你的
tp_traverse
函數包括以下內容:base->tp_traverse(self, visit, arg)
則要添加:
#if PY_VERSION_HEX >= 0x03090000 // This was not needed before Python 3.9 (bpo-35810 and bpo-40217) if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) { // a heap type's tp_traverse already visited Py_TYPE(self) } else { Py_VISIT(Py_TYPE(self)); } #else
PyEval_CallObject
,PyEval_CallFunction
,PyEval_CallMethod
和PyEval_CallObjectWithKeywords
函數已被棄用。 請改用PyObject_Call()
及其變化形式。 (詳情參見(jiàn) bpo-29548。)
CPython 字節碼的改變?
添加了
LOAD_ASSERTION_ERROR
操作碼用于處理assert
語(yǔ)句。 在之前的版本中,如果AssertionError
異常被屏蔽則 assert 語(yǔ)句將不能正常運作。 (由 Zackery Spytz 在 bpo-34880 中貢獻。)COMPARE_OP
操作碼已被拆分為四個(gè)單獨指令:COMPARE_OP
用于富比較IS_OP
用于 'is' 和 'is not' 檢測CONTAINS_OP
用于 'in' 和 'not in' 檢測JUMP_IF_NOT_EXC_MATCH
用于檢查 'try-except' 語(yǔ)句中的異常。
(由 Mark Shannon 在 bpo-39156 中貢獻。)
構建的改變?
將
--with-platlibdir
選項添加到configure
腳本:平臺專(zhuān)屬庫目錄的名稱(chēng),保存在新的sys.platlibdir
屬性中。 請參閱sys.platlibdir
屬性了解詳情。 (由 Jan Matějek, Matěj Cepl, Charalampos Stratakis 和 Victor Stinner 在 bpo-1294959 中貢獻。)COUNT_ALLOCS
特殊構建宏已被移除。 (由 Victor Stinner 在 bpo-39489 中貢獻。)在非 Windows 平臺上,現在需要用
setenv()
和unsetenv()
函數來(lái)構建 Python。 (由 Victor Stinner 在 bpo-39395 中貢獻。)在非 Windows 平臺上,創(chuàng )建
bdist_wininst
安裝器現在已不受官方支持。 (詳情參見(jiàn) bpo-10945。)When building Python on macOS from source,
_tkinter
now links with non-system Tcl and Tk frameworks if they are installed in/Library/Frameworks
, as had been the case on older releases of macOS. If a macOS SDK is explicitly configured, by using--enable-universalsdk
or-isysroot
, only the SDK itself is searched. The default behavior can still be overridden with--with-tcltk-includes
and--with-tcltk-libs
. (Contributed by Ned Deily in bpo-34956.)Python 現在可以針對 Windows 10 ARM64 進(jìn)行編譯。 (由 Steve Dower 在 bpo-33125 中貢獻。)
現在當使用
--pgo
時(shí)一些單獨的測試會(huì )被跳過(guò)。 這些測試顯著(zhù)增加了 PGO 任務(wù)的時(shí)間并且可能無(wú)助于提升最終可執行文件的優(yōu)化程度。 這樣能使任務(wù)加速大約 15 倍。 運行完整的單元測試是很慢的。 這個(gè)改變可能導致優(yōu)化程序稍差的構建,因為將被執行的代碼分支不夠多。 如果你愿意等待更緩慢的構建,則可以使用./configure [..] PROFILE_TASK="-m test --pgo-extended"
來(lái)恢復舊版本的行為。 我們不保證哪個(gè) PGO 任務(wù)集能產(chǎn)生更快的構建。 關(guān)心此問(wèn)題的用戶(hù)應當自行運行相關(guān)基準測試,因為結果可能取決于具體環(huán)境、工作負載以及編譯工具鏈。 (請參閱 bpo-36044 和 bpo-37707 了解詳情。)
C API 的改變?
新的特性?
PEP 573: 添加了
PyType_FromModuleAndSpec()
用于通過(guò)類(lèi)來(lái)關(guān)聯(lián)一個(gè)模塊;PyType_GetModule()
和PyType_GetModuleState()
用于獲取模塊及其狀態(tài);以及PyCMethod
和METH_METHOD
用于允許一個(gè)方法訪(fǎng)問(wèn)其定義所在的類(lèi)。 (由 Marcel Plch 和 Petr Viktorin 在 bpo-38787 中貢獻。)增加了
PyFrame_GetCode()
函數:獲取幀代碼。 增加了PyFrame_GetBack()
函數:獲取幀的下一個(gè)外部幀。 (由 Victor Stinner 在 bpo-40421 中貢獻。)將
PyFrame_GetLineNumber()
添加到受限的 C API。 (由 Victor Stinner 在 bpo-40421 中貢獻。)增加了
PyThreadState_GetInterpreter()
和PyInterpreterState_Get()
函數用于獲取解釋器。 增加了PyThreadState_GetFrame()
函數用于獲取 Python 線(xiàn)程狀態(tài)的當前幀。 增加了PyThreadState_GetID()
函數:獲取 Python 線(xiàn)程狀態(tài)的唯一標識符。 (由 Victor Stinner 在 bpo-39947 中貢獻。)將新的公有
PyObject_CallNoArgs()
函數添加到 C API,該函數可不帶任何參數調用一個(gè) Python 可調用對象。 它是不帶參數調用 Python 可調用對象最有效率的方式。 (由 Victor Stinner 在 bpo-37194 中貢獻。)受限 C API 中的改變(如果定義了
Py_LIMITED_API
宏):提供
Py_EnterRecursiveCall()
和Py_LeaveRecursiveCall()
作為常規函數用于受限 API。 在之前版本中是使用宏定義,但這些宏不能與無(wú)法訪(fǎng)問(wèn)PyThreadState.recursion_depth
字段的受限 C API 一同編譯(該結構體在受限 C API 中是不透明的)。PyObject_INIT()
和PyObject_INIT_VAR()
已成為常規“不透明”函數以隱藏實(shí)現細節。
增加了
PyModule_AddType()
函數以協(xié)助將類(lèi)型加入到模塊中。 (由 Dong-hee Na 在 bpo-40024 中貢獻。)將
PyObject_GC_IsTracked()
和PyObject_GC_IsFinalized()
函數添加到公有 API 以允許分別查詢(xún) Python 對象當前是正在被追蹤還是已經(jīng)被垃圾回收器所終結。 (由 Pablo Galindo Salgado 在 bpo-40241 中貢獻。)增加了
_PyObject_FunctionStr()
以獲取函數類(lèi)對象的用戶(hù)友好的表示形式。 (由 Jeroen Demeyer 在 bpo-37645 中修正。)增加了
PyObject_CallOneArg()
用于調用具有一個(gè)位置參數的對象(由 Jeroen Demeyer 在 bpo-37483 中修正。)
移植到 Python 3.9?
PyInterpreterState.eval_frame
(PEP 523) 現在需要有新的強制性形參 tstate (PyThreadState*
)。 (由 Victor Stinner 在 bpo-38500 中貢獻。)擴展模塊:
PyModuleDef
的m_traverse
,m_clear
和m_free
等函數在模塊狀態(tài)被請求但尚未被分配時(shí)將不會(huì )再被調用。 這種情況出現在模塊被創(chuàng )建之后且模塊被執行 (Py_mod_exec
函數) 之前的時(shí)刻。 更準確地說(shuō),這些函數在m_size
大于 0 并且模塊狀態(tài)(即PyModule_GetState()
的返回值)為NULL
時(shí)將不會(huì )被調用。沒(méi)有模塊狀態(tài)的擴展模塊 (
m_size <= 0
) 不會(huì )受到影響。現在如果
Py_AddPendingCall()
是在子解釋器內部被調用,該函數會(huì )被排入子解釋器的調用日程,而不是由主解釋器調用。 每個(gè)子解釋器現在都擁有它們自己的調用日程列表。 (由 Victor Stinner 在 bpo-39984 中貢獻。)當
-E
選項被使用 (如果PyConfig.use_environment
設為0
) 時(shí)將不再使用 Windows 注冊表來(lái)初始化sys.path
。 這會(huì )影響在 Windows 上嵌入 Python 的操作。 (由 Zackery Spytz 在 bpo-8901 中貢獻。)全局變量
PyStructSequence_UnnamedField
現在為常量并且指向一個(gè)字符串常量。 (由 Serhiy Storchaka 在 bpo-38650 中貢獻。)現在
PyGC_Head
結構是不透明的。 它只在內部 C API (pycore_gc.h
) 中定義。 (由 Victor Stinner 在 bpo-40241 中貢獻。)Py_UNICODE_COPY
,Py_UNICODE_FILL
,PyUnicode_WSTR_LENGTH
,PyUnicode_FromUnicode()
,PyUnicode_AsUnicode()
,_PyUnicode_AsUnicode
以及PyUnicode_AsUnicodeAndSize()
在 C 中被標記為已棄用。 它們自 Python 3.3 起就已被 PEP 393 棄用。 (由 Inada Naoki 在 bpo-36346 中貢獻。)Py_FatalError()
函數會(huì )被一個(gè)自動(dòng)記錄當前函數名稱(chēng)的宏所替代,除非已定義了Py_LIMITED_API
宏。 (由 Victor Stinner 在 bpo-39882 中貢獻。)vectorcall 協(xié)議現在要求調用者只傳入字符串作為鍵名。 (請參閱 bpo-37540 了解詳情。)
多個(gè)宏和函數的實(shí)現細節現在已被隱藏:
PyObject_IS_GC()
宏已被轉換為函數。PyObject_NEW()
宏已成為PyObject_New()
宏的別名,而PyObject_NEW_VAR()
宏已成為PyObject_NewVar()
宏的別名。 它們將不再直接訪(fǎng)問(wèn)PyTypeObject.tp_basicsize
成員。PyObject_GET_WEAKREFS_LISTPTR()
宏已被轉換為函數:該宏會(huì )直接訪(fǎng)問(wèn)PyTypeObject.tp_weaklistoffset
成員。PyObject_CheckBuffer()
宏已被轉換為函數:該宏會(huì )直接訪(fǎng)問(wèn)PyTypeObject.tp_as_buffer
成員。現在
PyIndex_Check()
總是被聲明為不透明函數以隱藏實(shí)現細節;PyIndex_Check()
宏已被移除。 該宏會(huì )直接訪(fǎng)問(wèn)PyTypeObject.tp_as_number
成員。
(詳情請參閱 bpo-40170。)
移除?
pyfpe.h
的PyFPE_START_PROTECT()
和PyFPE_END_PROTECT()
宏已從受限的 C API 中被排除。 (由 Victor Stinner 在 bpo-38835 中貢獻。)PyTypeObject 的
tp_print
空位已被移除。 它在 Python 2.7 及之前的版本中被用來(lái)將對象打印到文件。 自 Python 3.0 起,它已被忽略并且不再使用。 (由 Jeroen Demeyer 在 bpo-36974 中貢獻。)受限 C API 中的改變(如果定義了
Py_LIMITED_API
宏):以下函數已從受限 C API 中排除:
PyThreadState_DeleteCurrent()
(由 Joannah Nanjekye 在 bpo-37878 中貢獻。)_Py_CheckRecursionLimit
_Py_NewReference()
_Py_ForgetReference()
_PyTraceMalloc_NewReference()
_Py_GetRefTotal()
在受限 C API 中從未使用的垃圾箱機制。
PyTrash_UNWIND_LEVEL
Py_TRASHCAN_BEGIN_CONDITION
Py_TRASHCAN_BEGIN
Py_TRASHCAN_END
Py_TRASHCAN_SAFE_BEGIN
Py_TRASHCAN_SAFE_END
已將下列函數和定義移至內部 C API:
_PyDebug_PrintTotalRefs()
_Py_PrintReferences()
_Py_PrintReferenceAddresses()
_Py_tracemalloc_config
_Py_AddToAllObjects()
(Py_TRACE_REFS
構建專(zhuān)屬)
移除了
_PyRuntime.getframe
鉤子并移除了_PyThreadState_GetFrame
宏,該宏是_PyRuntime.getframe
的一個(gè)別名。 它們僅由內部 C API 對外公開(kāi)。 同樣地移除了PyThreadFrameGetter
類(lèi)型。 (由 Victor Stinner 在 bpo-39946 中貢獻。)從 C API 移除了下列函數。 請顯式地調用
PyGC_Collect()
來(lái)清空所有自由列表。 (由 Inada Naoki 和 Victor Stinner 在 bpo-37340, bpo-38896 和 bpo-40428 中貢獻。)PyAsyncGen_ClearFreeLists()
PyContext_ClearFreeList()
PyDict_ClearFreeList()
PyFloat_ClearFreeList()
PyFrame_ClearFreeList()
PyList_ClearFreeList()
PyMethod_ClearFreeList()
和PyCFunction_ClearFreeList()
: 綁定方法對象的自由列表已被移除。PySet_ClearFreeList()
: 集合自由列表已在 Python 3.4 中被移除。PyTuple_ClearFreeList()
PyUnicode_ClearFreeList()
: Unicode 自由列表已在 Python 3.3 中被移除。
移除了
_PyUnicode_ClearStaticStrings()
函數。 (由 Victor Stinner 在 bpo-39465 中貢獻。)移除了
Py_UNICODE_MATCH
。 它已被 PEP 393 所棄用,并自 Python 3.3 起不再可用。 可以改用PyUnicode_Tailmatch()
函數。 (由 Inada Naoki 在 bpo-36346 中貢獻。)清除了已定義但未實(shí)現的接口的頭文件。 被移除了公共 API 符號有:
_PyBytes_InsertThousandsGroupingLocale
,_PyBytes_InsertThousandsGrouping
,_Py_InitializeFromArgs
,_Py_InitializeFromWideArgs
,_PyFloat_Repr
,_PyFloat_Digits
,_PyFloat_DigitsInit
,PyFrame_ExtendStack
,_PyAIterWrapper_Type
,PyNullImporter_Type
,PyCmpWrapper_Type
,PySortWrapper_Type
,PyNoArgsFunction
。 (由 Pablo Galindo Salgado 在 bpo-39372 中貢獻。)
Python 3.9.1 中的重要變化?
typing?
typing.Literal
的行為被改為遵循 PEP 586 并匹配該 PEP 所描述的靜態(tài)類(lèi)型檢查器的行為。
Literal
現在將是去重復的形參。Literal
對象間的相等性比較現在將是順序無(wú)關(guān)的。Literal
比較現在會(huì )考慮類(lèi)型。 例如Literal[0] == Literal[False]
之前的結果值為True
。 現在則為False
。 為支持此改變,內部使用的類(lèi)型緩存現在也支持區分類(lèi)型。現在如果有任何一個(gè)參數不為 hashable,
Literal
對象將在相等性比較期間引發(fā)TypeError
。 請注意使用可變參數聲明Literal
將不會(huì )拋出異常:>>> from typing import Literal >>> Literal[{0}] >>> Literal[{0}] == Literal[{False}] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'set'
(由 Yurii Karabas 在 bpo-42345 中貢獻。)
macOS 11.0 (Big Sur) 與 Apple Silicon Mac 支持?
對于 3.9.1 版來(lái)說(shuō),Python 現在完全支持在 macOS 11.0 (Big Sur) 和 Apple Silicon Macs (基于 ARM64
架構) 上構建和運行。 現在提供了一個(gè)新的通用構建類(lèi)型 universal2
,用于在一組可執行文件上原生支持 ARM64
和 Intel 64
。 二進(jìn)制文件現在也可以在當前版本的 macOS 上編譯以部署到多種較舊的 macOS 版本上 (已測試 10.9),同時(shí)會(huì )基于運行時(shí)所使用的操作系統版本讓某些較新的 OS 功能和選項有條件地可用 ("弱鏈接") 。
(由 Ronald Oussoren 和 Lawrence D'Anna 在 bpo-41100 中貢獻。)
Python 3.9.2 中的重要變化?
collections.abc?
現在 collections.abc.Callable
泛型會(huì )將類(lèi)型形參展平,類(lèi)似于 typing.Callable
當前所做的那樣。 這意味著(zhù) collections.abc.Callable[[int, str], str]
的 __args__
將為 (int, str, str)
;之前則為 ([int, str], str)
。 為了允許這個(gè)改變,types.GenericAlias
現在可以被子類(lèi)化,并且在抽取 collections.abc.Callable
類(lèi)型時(shí)將返回一個(gè)子類(lèi)。 通過(guò) typing.get_args()
或 __args__
訪(fǎng)問(wèn)參數的代碼需要考慮到這個(gè)改變。 對于無(wú)效的 collections.abc.Callable
參數化形式可能會(huì )發(fā)出 DeprecationWarning
,這在 Python 3.9.1 中可能會(huì )靜默地傳遞。 這個(gè) DeprecationWarning
將在 Python 3.10 中變?yōu)?TypeError
。 (由 Ken Jin 在 bpo-42195 中貢獻。)
urllib.parse?
早先的 Python 版本允許使用 ;
和 &
作為 urllib.parse.parse_qs()
和 urllib.parse.parse_qsl()
中 query 形參的分隔鍵。 出于安全考慮,也為了遵循更新的 W3C 推薦設置,這已被改為只允許單個(gè)分隔鍵,默認為 &
。 這一改變還會(huì )影響 cgi.parse()
和 cgi.parse_multipart()
因為它們在內部使用了受影響的函數。 要了解更多細節,請查看它們各自的文檔。 (由 Adam Goldschmidt, Senthil Kumaran 和 Ken Jin 在 bpo-42967 中貢獻。)