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