Python 3.12 有什麼新功能¶
- 編輯者:
Adam Turner
本文介紹了 Python 3.12 與 3.11 相比多了哪些新功能。Python 3.12 於 2023 年 10 月 2 日發布。完整詳情請見 changelog。
也參考
PEP 693 -- Python 3.12 發布時程
發布重點摘要¶
Python 3.12 是 Python 程式語言的穩定版本,包含了語言和標準函式庫的綜合變更。標準函式庫的變更主要集中在清理棄用的 API、可用性和正確性。值得注意的是,distutils 套件已從標準函式庫中移除。os 和 pathlib 中的檔案系統支援進行了許多改進,並且有數個模組得到更好的效能。
語言變更主要集中在可用性,因為 f-字串已經移除了許多限制,並且持續改進 'Did you mean ...' 建議。新的型別參數語法和 type 陳述式改進了泛型型別和型別別名在與靜態型別檢查器一起使用上的效率。
這篇文章並不試圖提供所有新功能的完整規格,而是提供一個方便的概覽。完整詳情應參考文件,如標準函式庫參考和語言參考。如果你想了解某個新功能的完整實作和設計理念,請參考該功能的 PEP;但請注意 PEP 通常在功能完全實作後就不再更新。
新增語法特性:
新增語法特性:
直譯器改進:
PEP 669,低影響監控
改進了
NameError、ImportError和SyntaxError例外的「你的意思是... (Did you mean ...)」建議
Python 資料模型改進:
標準函式庫中的顯著改進:
pathlib.Path類別現在支援子類別化os模組在 Windows 支援上有了數項改進isinstance()對可在 runtime 檢查的協定的檢查速度可提高 2 到 20 倍asyncio套件進行了許多效能改進,一些基準測試顯示速度提高了 75%。
安全性改進:
將於
hashlib中 SHA1、SHA3、SHA2-384、SHA2-512 和 MD5 內建實作替換為來自 HACL* 專案的經正式驗證的程式碼。這些內建實作仍然作為備援方案 (fallback),僅在 OpenSSL 不提供它們時使用。
C API 改進:
CPython 實作改進:
PEP 709,行內綜合運算 (comprehension inlining)
對 Linux
perf分析器的 CPython 支援在支援的平台上實作堆疊溢位保護
新增型別特性:
重要的棄用、刪除或限制:
PEP 623:從 Python C API 中的 Unicode 物件中刪除
wstr,將每個str物件的大小減少至少 8 個位元組。PEP 632:刪除
distutils套件。請參閱遷移指南以查看替換原有 API 的建議。如果你在 Python 3.12 及後續版本中仍然需要它們,第三方套件 Setuptools 會繼續提供distutils。gh-95299:不再於以
venv建立的虛擬環境中預先安裝setuptools。這意味著distutils、setuptools、pkg_resources和easy_install將預設不可用;若要使用這些工具,請在已啟用的虛擬環境中執行pip install setuptools。asynchat、asyncore和imp模組以及幾個unittest.TestCase的方法別名已被刪除。
新增功能¶
PEP 695:型別參數語法¶
PEP 484 下的泛型類別和函式是使用較冗長語法來宣告,這使得型別參數的作用域不明確,並且需要顯式地宣告變異數 (variance)。
PEP 695 引入了一種新的、更簡潔和顯式的方法來建立泛型類別和函式:
def max[T](args: Iterable[T]) -> T:
...
class list[T]:
def __getitem__(self, index: int, /) -> T:
...
def append(self, element: T) -> None:
...
此外,PEP 引入了一種使用型別陳述式來宣告型別別名的新方法,該方法會建立一個 TypeAliasType 的實例:
type Point = tuple[float, float]
型別別名也可以是泛型:
type Point[T] = tuple[T, T]
新的語法允許宣告 TypeVarTuple 和 ParamSpec 參數,以及帶有邊界 (bounds) 或限制 (constraints) 的 TypeVar 參數:
type IntFunc[**P] = Callable[P, int] # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T] # 帶有邊界的 TypeVar
type IntOrStrSequence[T: (int, str)] = Sequence[T] # 帶有限制的 TypeVar
透過此語法建立之型別別名的值和型別變數的邊界和限制,僅會根據需求來求值(請參閱延遲求值 (lazy evaluation))。這意味著型別別名可以參照在檔案中後續定義的其他型別。
透過型別參數串列宣告的型別參數在宣告作用域及任何巢狀作用域內皆為可見,但在外部作用域內不可見。例如,它們可以用在泛型類別方法的型別註釋中或類別主體中。但是,在定義類別後,它們不能在模組作用域內使用。有關型別參數的 runtime 語義的詳細描述,請參閱 Type parameter lists。
為了支援這些作用域語義而引入了一種新的作用域,即註釋作用域 (annotation scope)。註釋作用域的行為在很大程度上類似於函式作用域,但與封閉類別作用域的交互方式不同。在 Python 3.13 中,註釋也將在註釋作用域內進行求值。
詳情請見 PEP 695。
(PEP 由 Eric Traut 撰寫。由 Jelle Zijlstra、Eric Traut 和其他人在 gh-103764 中實作。)
PEP 701:f 字串的語法形式化¶
PEP 701 解除了 f 字串在使用上的一些限制。f 字串內的運算式元件現在可以是任何有效的 Python 運算式,包括重複使用與包含 f 字串相同的引號的字串、多行運算式、註解、反斜線和 unicode 轉義序列。讓我們詳細介紹一下這些內容:
引號重用:在 Python 3.11 中,重複使用與封閉的 f 字串相同的引號會引發
SyntaxError,強制使用者使用其他可用的引號(例如,如果 f 字串使用單引號,則使用雙引號或三引號)。在 Python 3.12 中,你現在可以執行以下操作:>>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism'] >>> f"This is the playlist: {", ".join(songs)}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
請注意,在此更改之前,對於如何嵌套 f 字串沒有明確的限制,但事實上字串引號不能在 f 字串的運算式元件內重複使用,因此無法任意嵌套 f 字串。事實上,這是嵌套層數最多的 f 字串:
>>> f"""{f'''{f'{f"{1+1}"}'}'''}""" '2'
由於現在 f 字串可以在運算式元件內包含任何有效的 Python 運算式,因此現在可以任意嵌套 f 字串:
>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2'
多行運算式和註解:在 Python 3.11 中,f 字串運算式必須在單行中定義,即使 f 字串中的運算式通常可以跨越多行(就像在多行上定義的 list 常值一樣),從而使它們更難閱讀。在 Python 3.12 中,你現在可以定義跨越多行的 f 字串,並新增內嵌註解:
>>> f"This is the playlist: {", ".join([ ... 'Take me back to Eden', # My, my, those eyes like fire ... 'Alkaline', # Not acid nor alkaline ... 'Ascensionism' # Take to the broken skies at last ... ])}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'反斜線和 unicode 字元:在 Python 3.12 之前,f 字串運算式不能包含任何
\字元。這也影響了 unicode 轉義序列(例如\N{snowman}),因為它們包含\N部分,該部分以前不能是 f 字串運算式元件的一部分。現在,你可以像這樣定義運算式:>>> print(f"This is the playlist: {"\n".join(songs)}") This is the playlist: Take me back to Eden Alkaline Ascensionism >>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}") This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism
詳情請見 PEP 701。
作為此功能實作方式的積極副作用(透過使用 PEG 剖析器 剖析 f 字串),現在 f 字串的錯誤訊息更加精確,並且包含錯誤的確切位置。例如,在 Python 3.11 中,以下 f 字串會引發 SyntaxError:
>>> my_string = f"{x z y}" + f"{1 + 1}"
File "<stdin>", line 1
(x z y)
^^^
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?
但錯誤訊息不包括行內錯誤的確切位置,並且還人為地將運算式用括號括起來。在 Python 3.12 中,由於使用 PEG 剖析器剖析 f 字串,因此錯誤訊息可以更精確並顯示整行:
>>> my_string = f"{x z y}" + f"{1 + 1}"
File "<stdin>", line 1
my_string = f"{x z y}" + f"{1 + 1}"
^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
(由 Pablo Galindo、Batuhan Taskaya、Lysandros Nikolaou、Cristián Maureira-Fredes 和 Marta Gómez 在 gh-102856 中貢獻。PEP 由 Pablo Galindo、Batuhan Taskaya、Lysandros Nikolaou 和 Marta Gómez 編寫)。
PEP 684:直譯器各別持有的 GIL¶
PEP 684 引入了直譯器各別持有的 GIL,因此子直譯器現在可以使用各個直譯器特有的 GIL 來建立。這使得 Python 程式可以充分利用多個 CPU 核心。目前這僅透過 C-API 使用,不過 Python API 預計在 3.13 中提供。
使用新的 Py_NewInterpreterFromConfig() 函式建立一個具有自己的 GIL 的直譯器:
PyInterpreterConfig config = {
.check_multi_interp_extensions = 1,
.gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {
return -1;
}
/* 新的直譯器現在會在目前執行緒中啟用。 */
關於如何使用子直譯器的 C API 搭配各直譯器獨立的 GIL 的更多範例,請參見 Modules/_xxsubinterpretersmodule.c。
(由 Eric Snow 於 gh-104210 等貢獻。)
PEP 669:CPython 的低影響監控¶
PEP 669 定義了一個新的 API ,用於分析器、偵錯器和其他工具來監視 CPython 中的事件。它涵蓋了廣泛的事件,包括呼叫、回傳、行、例外、跳躍等等。這意味著你只需為所使用的功能承擔開銷,為接近零開銷的偵錯器和覆蓋率工具提供支援。有關詳細資訊,請參閱 sys.monitoring。
(由 Mark Shannon 於 gh-103082 中貢獻。)
PEP 688:使緩衝區協定可在 Python 中存取¶
PEP 688 引入了一種從 Python 程式碼使用 緩衝區協定 的方法。實作 __buffer__() 方法的類別現在可用作緩衝區型別。
新的 collections.abc.Buffer ABC 提供了一種表示緩衝區物件的標準方法,例如在型別註釋中。新的 inspect.BufferFlags 列舉表示可用於自訂緩衝區建立的旗標。(由 Jelle Zijlstra 在 gh-102500 中貢獻。)
PEP 709:行內綜合運算¶
字典、串列和集合綜合運算現在是行內的,而不是為綜合運算的每次執行建立一個新的一次性函式物件。這可以將綜合運算的執行速度提高兩倍。請參閱 PEP 709 以了解更多詳細資訊。
綜合運算的疊代變數保持隔離,不會覆蓋外部作用域中的同名變數,綜合運算後它們也不可見。行內化確實會導致一些明顯的行為改變:
回溯中不再有用於綜合運算的單獨堆疊框架,並且追蹤/分析不再將綜合運算顯示為函式呼叫。
symtable模組將不再為每個綜合運算產生子符號表;相反,綜合運算的局部變數將包含在父函式的符號表中。現在,在綜合運算內呼叫
locals()包含來自綜合運算外部的變數,並且不再包含用於綜合運算參數的合成.0變數。當在追蹤下執行(例如程式碼覆蓋率測量)時,直接疊代
locals()(例如[k for k in locals()])的綜合運算可能會看到 "RuntimeError: dictionary changed size during iteration"。這與在for k in locals():中已經看到的行為相同。為了避免錯誤,首先建立一個要疊代的鍵串列:keys = list(locals()); [k for k in keys]。
(由 Carl Meyer 和 Vladimir Matveev 於 PEP 709 中貢獻。)
改善錯誤訊息¶
當
NameError提升到頂層時,標準函式庫中的模組現在可能會被建議作為直譯器顯示的錯誤訊息的一部分。(由 Pablo Galindo 在 gh-98254 中貢獻。)>>> sys.version_info Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sys' is not defined. Did you forget to import 'sys'?
改進實例的
NameError例外的錯誤建議。現在,如果在方法中引發NameError並且該實例具有與例外中的名稱完全相同的屬性,則建議將包含self.<NAME>而不是方法作用域中的最接近匹配。(由 Pablo Galindo 在 gh-99139 中貢獻。)>>> class A: ... def __init__(self): ... self.blech = 1 ... ... def foo(self): ... somethin = blech ... >>> A().foo() Traceback (most recent call last): File "<stdin>", line 1 somethin = blech ^^^^^ NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
改進當使用者鍵入
import x from y而不是from y import x時出現的SyntaxError錯誤訊息。(由 Pablo Galindo 在 gh-98931 中貢獻。)>>> import a.y.z from b.y.z Traceback (most recent call last): File "<stdin>", line 1 import a.y.z from b.y.z ^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Did you mean to use 'from ... import ...' instead?
由失敗的
from <module> import <name>陳述式引發的ImportError例外現在包含基於<module>中可用名稱的<name>值的建議。(由 Pablo Galindo 在 gh-91058 中貢獻。)>>> from collections import chainmap Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
其他語言更動¶
現在,剖析器在剖析包含空位元組的源程式碼時會引發
SyntaxError。(由 Pablo Galindo 在 gh-96670 中貢獻。)不是有效轉義序列的反斜線字元對現在會產生
SyntaxWarning,而不是DeprecationWarning。例如,re.compile("\d+\.\d+")現在發出一個SyntaxWarning("\d"是無效的轉義序列,請使用原始字串作為正規表示式:re.compile(r"\d+\.\d+"))。在未來的 Python 版本中,最終將引發SyntaxError,而不是SyntaxWarning。(由 Victor Stinner 在 gh-98401 中貢獻。)值大於
0o377的八進位轉義符(例如:"\477")在 Python 3.11 中已棄用,現在會生成SyntaxWarning,而不是DeprecationWarning。在未來的 Python 版本中,它們最終將成為SyntaxError。(由 Victor Stinner 在 gh-98401 中貢獻。)綜合運算目標部分中使用的未儲存的變數現在可以在賦值運算式中使用 (
:=)。例如,在[(b := 1) for a, b.prop in some_iter]中,現在允許對b進行賦值。請注意,根據 PEP 572 ,仍然不允許對儲存在綜合運算目標部分中的變數進行賦值(如a)。(由 Nikita Sobolev 在 gh-100581 中貢獻。)類別或型別的
__set_name__方法中引發的例外不再由RuntimeError包裝。上下文資訊會以 PEP 678 註解加入例外。(由 Irit Katriel 在 gh-77757 中貢獻。)當
try-except*構造處理整個ExceptionGroup並引發另一個例外時,該例外不再包裝在ExceptionGroup中。在 3.11.4 版本中也進行了更改。(由 Irit Katriel 在 gh-103590 中貢獻。)垃圾收集器現在僅在 Python 位元組碼評估迴圈的 eval 斷路器機制上運行,而不是在物件分配上運行。GC 也可以在呼叫
PyErr_CheckSignals()時運行,因此需要長時間運行而不執行任何 Python 程式碼的 C 擴充也有機會定期執行 GC。(由 Pablo Galindo 在 gh-97922 中貢獻。)所有需要布林參數的內建和擴充可呼叫物件現在接受任何型別的參數,而不僅僅是
bool和int。(由 Serhiy Storchaka 在 gh-60203 中貢獻。)memoryview現在支援半浮點型別("e" 格式碼)。(由 Donghee Na 和 Antoine Pitrou 在 gh-90751 中貢獻。)slice物件現在是可雜湊的,允許它們作為字典的鍵和集合的項。(由 Will Bradshaw、Furkan Onder 和 Raymond Hettinger 在 gh-101264 中貢獻。)sum()現在使用 Neumaier 求和來提高對浮點數或混合整數和浮點數求和時的準確性和交換性。(由 Raymond Hettinger 在 gh-100425 中貢獻。)現在,在剖析包含空位元組的源程式碼時,
ast.parse()會引發SyntaxError,而不是ValueError。(由 Pablo Galindo 在 gh-96670 中貢獻。)tarfile和shutil.unpack_archive()中的提取方法有一個新的 filter 參數,該參數允許限制可能令人驚訝或危險的 tar 功能,例如在目標目錄之外建立檔案。有關詳細資訊,請參閱tarfile 提取過濾器。在 Python 3.14 中,預設將切換為'data'。(由 Petr Viktorin 在 PEP 706 中貢獻。)如果底層對映是可雜湊的,則
types.MappingProxyType實例現在是可雜湊的。(由 Serhiy Storchaka 在 gh-87995 中貢獻。)透過新的環境變數
PYTHONPERFSUPPORT和命令列選項-X perf以及新的sys.activate_stack_trampoline()、sys.deactivate_stack_trampoline()和sys.is_stack_trampoline_active()函式,新增對效能分析器的支援。(由 Pablo Galindo 設計。由 Pablo Galindo 和 Christian Heimes 貢獻,Gregory P. Smith [Google] 和 Mark Shannon 在 gh-96123 中也有貢獻。)
新增模組¶
無。
改進的模組¶
array¶
array.array類別現在支援下標,使其成為泛型型別。(由 Jelle Zijlstra 在 gh-98658 中貢獻。)
asyncio¶
asyncio 中寫入 socket 的效能得到了顯著提高。
asyncio現在可以避免在寫入 socket 時進行不必要的複製,並在平台支援的情況下使用sendmsg()。(由 Kumar Aditya 在 gh-91166 中貢獻。)新增
asyncio.eager_task_factory()和asyncio.create_eager_task_factory()函式以允許選擇事件迴圈來執行急切任務,使某些用例速度提高 2 到 5 倍。(由 Jacob Bower 和 Itamar Oren 在 gh-102853、gh-104140 和 gh-104138 中貢獻)在 Linux 上,如果
os.pidfd_open()可用且功能正常,asyncio預設會使用asyncio.PidfdChildWatcher而非asyncio.ThreadedChildWatcher。(由 Kumar Aditya 在 gh-98024 中貢獻。)事件迴圈現在會為每個平台使用最佳的子行程監看器 (child watcher)(如果支援則使用
asyncio.PidfdChildWatcher,否則使用asyncio.ThreadedChildWatcher),因此不建議手動設定子行程監看器。(由 Kumar Aditya 在 gh-94597 中貢獻。)asyncio.run()新增 loop_factory 參數以允許指定自訂事件迴圈工廠函式。(由 Kumar Aditya 在 gh-99388 中貢獻。)新增
asyncio.current_task()的 C 實作,加速了 4-6 倍。(由 Itamar Oren 和 Pranav Thulasiram Bhat 在 gh-100344 中貢獻。)asyncio.iscoroutine()現在為產生器回傳False,因為asyncio不支援傳統的基於產生器的協程。(由 Kumar Aditya 在 gh-102748 中貢獻。)asyncio.wait()和asyncio.as_completed()現在接受使用產生器來生成任務。(由 Kumar Aditya 在 gh-78530 中貢獻。)
calendar¶
新增列舉
calendar.Month和calendar.Day來定義一年中的月份和一週的日期。(由 Prince Roshan 在 gh-103636 中貢獻。)
csv¶
新增
csv.QUOTE_NOTNULL和csv.QUOTE_STRINGS旗標,為reader和writer物件提供對None和空字串更細緻的控制。
dis¶
偽指令操作碼(由編譯器使用,但不會出現在可執行位元組碼中)現在在
dis模組中公開。HAVE_ARGUMENT仍然與真實操作碼相關,但對於偽指令沒有用處。請改用新的dis.hasarg集合。(由 Irit Katriel 在 gh-94216 中貢獻。)新增
dis.hasexc集合來表示設定例外處理程序的指令。(由 Irit Katriel 在 gh-94216 中貢獻。)
fractions¶
fractions.Fraction型別的物件現在支援浮點樣式格式化。(由 Mark Dickinson 在 gh-100161 中貢獻。)
importlib.resources¶
importlib.resources.as_file()現在支援資源目錄。(由 Jason R. Coombs 於 gh-97930 中貢獻。)將
importlib.resources.files()的第一個參數重新命名為 anchor。(由 Jason R. Coombs 於 gh-100598 中貢獻。)
inspect¶
新增
inspect.markcoroutinefunction()以標記會回傳 coroutine 的同步函式,以供inspect.iscoroutinefunction()使用。(由 Carlton Gibson 於 gh-99247 中貢獻。)新增
inspect.getasyncgenstate()和inspect.getasyncgenlocals()以確定非同步產生器的目前狀態。(由 Thomas Krennwallner 於 gh-79940 中貢獻。)inspect.getattr_static()的效能已大幅改善。大多數對該函式的呼叫應該比 Python 3.11 中快至少 2 倍。(由 Alex Waygood 於 gh-103193 中貢獻。)
itertools¶
新增
itertools.batched()以將元素收集到大小均等的元組中,其中最後一批次可能比其他的少。(由 Raymond Hettinger 於 gh-98363 中貢獻。)
math¶
新增
math.sumprod()以計算乘積總和。(由 Raymond Hettinger 於 gh-100485 中貢獻。)擴充
math.nextafter()來包含一個 steps 引數,用於一次向上或向下移動多步。(由 Matthias Goergens、Mark Dickinson 和 Raymond Hettinger 在 gh-94906 貢獻。)
os¶
新增
os.PIDFD_NONBLOCK以便在非阻塞模式下使用os.pidfd_open()為行程打開檔案描述器。(由 Kumar Aditya 在 gh-93312 中貢獻。)os.DirEntry現在包含一個os.DirEntry.is_junction()方法來檢查條目是否為連結點。(由 Charles Machalow 在 gh-99547 中貢獻。)在 Windows 上新增
os.listdrives()、os.listvolumes()和os.listmounts()函式,用於列舉磁碟機 (drives)、磁碟區 (volumes) 和掛載點 (mount points)。(由 Steve Dower 在 gh-102519 中貢獻。)os.stat()和os.lstat()現在在 Windows 上更加準確。st_birthtime欄位現在將填充檔案的建立時間,st_ctime已棄用,但仍包含建立時間(但將來將回傳最後一次元資料更改,以與其他平台保持一致)。根據你的檔案系統,st_dev可能高達 64 位元、st_ino高達 128 位元,並且st_rdev始終設定為零而不是錯誤的值。在較新版本的 Windows 上,這兩個功能可能會明顯更快。(由 Steve Dower 在 gh-99726 中貢獻。)
os.path¶
新增
os.path.isjunction()以檢查給定路徑是否為連結點 (junction)。(由 Charles Machalow 於 gh-99547 中貢獻。)新增
os.path.splitroot()以將路徑分割為三元組(drive, root, tail)。(由 Barney Gale 於 gh-101000 中貢獻。)
pathlib¶
新增對
pathlib.PurePath和pathlib.Path子類別化的支援,以及它們的 Posix 和 Windows 特定變體。子類別可以覆寫pathlib.PurePath.with_segments()方法以在路徑實例之間傳遞訊息。新增
pathlib.Path.walk()用於遍歷目錄樹並產生其中的所有檔案或目錄名稱,類似於os.walk()。(由 Stanislav Zmiev 在 gh-90385 中貢獻。)將可選參數 walk_up 新增至
pathlib.PurePath.relative_to()以允許在結果中插入..條目;此行為與os.path.relpath()更加一致。(由 Domenico Ragusa 在 gh-84538 中貢獻。)新增
pathlib.Path.is_junction()作為os.path.isjunction()的代理。(由 Charles Machalow 在 gh-99547 中貢獻。)為
pathlib.Path.glob()、pathlib.Path.rglob()和pathlib.PurePath.match()新增可選參數 case_sensitive,以匹配路徑的大小區分程度,從而更精確控制匹配過程。
platform¶
新增對 Windows 11 和 2012 之後的 Windows Server 版本的偵測支援。之前,在比 Windows Server 2012 更新的 Windows Server 平台和 Windows 11 上的查詢會回傳
Windows-10。(由 Steve Dower 在 gh-89545 中貢獻。)
pdb¶
新增方便的變數來暫時保存偵錯工作階段的值,並提供對當前幀或回傳值等值的快速存取。(由 Tian Gao 貢獻 gh-103693。)
random¶
新增
random.binomialvariate()。(由 Raymond Hettinger 於 gh-81620 中貢獻。)將預設值
lambd=1.0加入至random.expovariate()中。(由 Raymond Hettinger 在 gh-100234 中貢獻。)
shutil¶
shutil.make_archive()現在將 root_dir 引數傳遞給支援它的自訂歸檔器。在這種情況下,它不再暫時將行程的當前工作目錄更改為 root_dir 來執行歸檔。(由 Serhiy Storchaka 在 gh-74696 中貢獻。)shutil.rmtree()現在接受一個新引數 onexc,它是一個類似於 onerror 的錯誤處理程序,但它需要一個例外實例而不是 (typ, val, tb) 三元組。onerror 已棄用。(由 Irit Katriel 在 gh-102828 中貢獻。)shutil.which()現在會查閱 PATHEXT 環境變數來查找 Windows 上 PATH 內的匹配項,即使給定的 cmd 包含目錄元件也是如此。(由 Charles Machalow 在 gh-103179 中貢獻。)在 Windows 上查詢可執行檔時,
shutil.which()將呼叫NeedCurrentDirectoryForExePathW以確定是否應將當前工作目錄新增到搜尋路徑前面。(由 Charles Machalow 在 gh-103179 中貢獻。)shutil.which()將優先回傳 cmd 與PATHEXT中元件相匹配的路徑,然後才在 Windows 搜尋路徑中的其他位置進行直接匹配。(由 Charles Machalow 在 gh-103179 中貢獻。)
sqlite3¶
將
sqlite3.Connection.autocommit屬性加入sqlite3.Connection並將 autocommit 參數加入sqlite3.connect()以控制與 PEP 249 相容的事務處理。(由 Erlend E. Aasland 在 gh-83638 中貢獻。)將僅關鍵字參數 entrypoint 新增至
sqlite3.Connection.load_extension(),以覆蓋 SQLite 擴充進入點。(由 Erlend E. Aasland 在 gh-103015 中貢獻。)將
sqlite3.Connection.getconfig()和sqlite3.Connection.setconfig()新增至sqlite3.Connection以對資料庫連線進行設定變更。(由 Erlend E. Aasland 在 gh-103489 中貢獻。)
statistics¶
擴充
statistics.correlation()以包含為計算排名資料的 Spearman 相關性的ranked方法。(由 Raymond Hettinger 在 gh-95861 中貢獻。)
sys¶
新增
sys.monitoring命名空間以公開新的 PEP 669 監控 API。(由 Mark Shannon 在 gh-103082 中貢獻。)新增
sys.activate_stack_trampoline()和sys.deactivate_stack_trampoline()用於啟用和停用堆疊分析器 trampolines,以及sys.is_stack_trampoline_active()用於查詢堆疊分析器 trampolines 是否處於活躍狀態。(由 Pablo Galindo 、 Christian Heimes、Gregory P. Smith [Google] 和 Mark Shannon 在 gh-96123 中貢獻。)新增
sys.last_exc,它保存最後一個引發的未處理例外(用於事後偵錯)。棄用舊格式中具有相同資訊的三個欄位:sys.last_type、sys.last_value和sys.last_traceback。(由 Irit Katriel 在 gh-102778 中貢獻。)sys._current_exceptions()現在回傳從執行緒 id 到例外實例的對映,而不是(typ, exc, tb)元組。(由 Irit Katriel 在 gh-103176 中貢獻。)sys.setrecursionlimit()和sys.getrecursionlimit()。遞迴限制現在僅適用於 Python 程式碼。內建函式不使用遞迴限制,但受到不同機制的保護,以防止遞迴導致虛擬機器崩潰。
tempfile¶
tempfile.NamedTemporaryFile函式新增了一個選擇性參數 delete_on_close (由 Evgeny Zorin 於 gh-58451 中貢獻。)tempfile.mkdtemp()現在總是會傳回絕對路徑,即使提供給 dir 參數的引數是相對路徑。
threading¶
新增
threading.settrace_all_threads()和threading.setprofile_all_threads(),允許在除呼叫執行緒之外的所有正在運行的執行緒中設定追蹤 (tracing) 和分析 (profiling) 函式。(由 Pablo Galindo 在 gh-93503 中貢獻。)
tkinter¶
tkinter.Canvas.coords()現在將其參數展平。它現在不僅接受座標作為單獨的引數 (x1, y1, x2, y2, ...) 和一系列座標 ([x1, y1, x2, y2, ...]),而且還有成對分組的座標 ((x1, y1), (x2, y2), ...和[(x1, y1), (x2, y2), ...]),如create_*()方法。(由 Serhiy Storchaka 在 gh-94473 中貢獻。)
tokenize¶
tokenize模組包含 PEP 701 中引入的變更。(由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中貢獻。)有關tokenize模組更改的更多資訊,請參閱 移植至 Python 3.12。
types¶
新增
types.get_original_bases()以允許在子類別化時進一步內省 (introspect) 使用者定義的泛型。(由 James Hilton-Balfe 和 Alex Waygood 在 gh-101827 中貢獻。)
typing¶
isinstance()針對可在 runtime 檢查的協定的檢查,現在使用inspect.getattr_static()而不是hasattr()來查找屬性是否存在。這意味著在針對 可在 runtime 檢查的協定的isinstance()檢查期間,描述器和__getattr__()方法不再意外地被求值。然而,這也可能意味著一些曾經被視為 可在 runtime 檢查的協定實例的物件在 Python 3.12+ 上可能不再被視為該協定的實例,反之亦然。大多數使用者不太可能受到此更改的影響。(由 Alex Waygood 在 gh-102433 中貢獻。)現在,一旦建立了類別,可在 runtime 檢查的協定的成員就會在 runtime 被視為「凍結」。將屬性 monkey-patch 到 可在 runtime 檢查的協定上仍然有效,但不會影響將物件與協定進行比較的
isinstance()檢查。例如:>>> from typing import Protocol, runtime_checkable >>> @runtime_checkable ... class HasX(Protocol): ... x = 1 ... >>> class Foo: ... ... >>> f = Foo() >>> isinstance(f, HasX) False >>> f.x = 1 >>> isinstance(f, HasX) True >>> HasX.y = 2 >>> isinstance(f, HasX) # 沒有改變,即便 HasX 現在有 "y" 屬性 True
進行此更改是為了加快針對 可在 runtime 檢查的協定的
isinstance()檢查。isinstance()針對可在 runtime 檢查的協定進行檢查的效能概況已發生顯著變化。大多數isinstance()針對只有少數成員的協定的檢查應該比 3.11 中至少快 2 倍,有些可能快 20 倍或更多。然而,isinstance()對具有許多成員的協定進行檢查可能比 Python 3.11 慢。(由 Alex Waygood 在 gh-74690 和 gh-103193 中貢獻。)所有
typing.TypedDict和typing.NamedTuple類別現在都具有__orig_bases__屬性。 (由 Adrian Garcia Badaracco 在 gh-103699 中貢獻。)新增
frozen_default參數至typing.dataclass_transform()。(由 Erik De Bonte 於 gh-99957 中貢獻。)
unicodedata¶
Unicode 資料庫已更新至版本 15.0.0。(由 Benjamin Peterson 在 gh-96734 中貢獻)。
unittest¶
新增 --durations 命令列選項,顯示 N 個最慢的測試案例:
python3 -m unittest --durations=3 lib.tests.test_threading
.....
Slowest test durations
----------------------------------------------------------------------
1.210s test_timeout (Lib.test.test_threading.BarrierTests)
1.003s test_default_timeout (Lib.test.test_threading.BarrierTests)
0.518s test_timeout (Lib.test.test_threading.EventTests)
(0.000 durations hidden. Use -v to show these durations.)
----------------------------------------------------------------------
Ran 158 tests in 9.869s
OK (skipped=3)
(由 Giampaolo Rodola 於 gh-48330 中貢獻。)
uuid¶
最佳化¶
從 Unicode 物件中刪除
wstr和wstr_length成員。它在 64 位元平台上將物件大小減少了 8 或 16 位元組。(PEP 623)(由 Inada Naoki 在 gh-92536 貢獻。)增加在建置過程中使用 BOLT 二進位最佳化器的實驗支援,這可將效能提高 1-5%。(由 Kevin Modzelewski 在 gh-90536 中貢獻、由 Donghee Na 在 gh-101525 中調整)
將包含群組參照的替換字串的正規表示式替換(函式
re.sub()和re.subn()以及相應的re.Pattern方法)速度提高 2--3 倍。(由 Serhiy Storchaka 在 gh-91524 中貢獻。)透過延遲運算較繁重的字串格式化來加速
asyncio.Task的建立。(由 Itamar Oren 於 gh-103793 中貢獻。)作為覆蓋
tokenize模組中的 PEP 701 所需更改的副作用,tokenize.tokenize()和tokenize.generate_tokens()函式速度提高了 64%。(由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中貢獻。)透過新的
LOAD_SUPER_ATTR指令加速super()方法呼叫和屬性載入。(由 Carl Meyer 和 Vladimir Matveev 在 gh-103497 中貢獻。)
CPython 位元組碼變更¶
移除
LOAD_METHOD指令。它已經合併至LOAD_ATTR。LOAD_ATTR現在會像舊的LOAD_METHOD指令一樣行為,如果其 oparg 的低位元 (low bit) 有被設定。(由 Ken Jin 於 gh-93429 中貢獻。)移除
JUMP_IF_FALSE_OR_POP和JUMP_IF_TRUE_OR_POP指令。(由 Irit Katriel 於 gh-102859 中貢獻。)移除
PRECALL指令。(由 Mark Shannon 於 gh-92925 中貢獻。)新增
BINARY_SLICE和STORE_SLICE指令。(由 Mark Shannon 於 gh-94163 中貢獻。)新增
CALL_INTRINSIC_1指令。(由 Mark Shannon 於 gh-99005 中貢獻。)新增
CALL_INTRINSIC_2指令。(由 Irit Katriel 於 gh-101799 中貢獻。)新增
CLEANUP_THROW指令。(由 Brandt Bucher 於 gh-90997 中貢獻。)新增
END_SEND指令。(由 Mark Shannon 於 gh-103082 中貢獻。)新增
LOAD_FAST_AND_CLEAR指令作為 PEP 709 實作的一部分。(由 Carl Meyer 於 gh-101441 中貢獻。)新增
LOAD_FAST_CHECK指令。(由 Dennis Sweeney 於 gh-93143 中貢獻。)新增
LOAD_FROM_DICT_OR_DEREF、LOAD_FROM_DICT_OR_GLOBALS和LOAD_LOCALS操作碼作為 PEP 695 實作的一部分。移除LOAD_CLASSDEREF操作碼,可以用LOAD_LOCALS加上LOAD_FROM_DICT_OR_DEREF來取代。(由 Jelle Zijlstra 於 gh-103764 中貢獻。)新增
LOAD_SUPER_ATTR指令。(由 Carl Meyer 和 Vladimir Matveev 於 gh-103497 中貢獻。)新增
RETURN_CONST指令。(由 Wenyang Wang 於 gh-101632 中貢獻。)
演示和工具¶
刪除包含舊演示腳本的
Tools/demo/目錄。可以在 old-demos 專案中找到副本。(由 Victor Stinner 在 gh-97681 中貢獻。)刪除
Tools/scripts/目錄中過時的演示腳本。可以在 old-demos 專案中找到副本。(由 Victor Stinner 在 gh-97669 中貢獻。)
已棄用¶
argparse:argparse.BooleanOptionalAction的 type、choices 和 metavar 參數已被棄用,將在 3.14 中移除。(由 Nikita Sobolev 於 gh-92248 貢獻。)ast:以下ast功能自 Python 3.8 起已在文件中被棄用,現在在存取或使用時會在 runtime 發出DeprecationWarning,並將在 Python 3.14 中移除:ast.Numast.Strast.Bytesast.NameConstantast.Ellipsis
請改用
ast.Constant。(由 Serhiy Storchaka 於 gh-90953 貢獻。)-
已棄用並將在 Python 3.14 中移除的 child watcher 類別:
asyncio.MultiLoopChildWatcher、asyncio.FastChildWatcher、asyncio.AbstractChildWatcher和asyncio.SafeChildWatcher。(由 Kumar Aditya 於 gh-94597 貢獻。)asyncio.set_child_watcher()、asyncio.get_child_watcher()、asyncio.AbstractEventLoopPolicy.set_child_watcher()和asyncio.AbstractEventLoopPolicy.get_child_watcher()已被棄用並將在 Python 3.14 中移除。(由 Kumar Aditya 於 gh-94597 貢獻。)預設事件迴圈策略的
get_event_loop()方法現在會在沒有設定目前事件迴圈且決定建立一個時發出DeprecationWarning。(由 Serhiy Storchaka 和 Guido van Rossum 於 gh-100160 貢獻。)
calendar:calendar.January和calendar.February常數已被棄用並被calendar.JANUARY和calendar.FEBRUARY取代。(由 Prince Roshan 於 gh-103636 貢獻。)collections.abc:棄用collections.abc.ByteString。使用
isinstance(obj, collections.abc.Buffer)來測試obj是否在 runtime 實作了緩衝區協定。在型別註解的使用中,請用Buffer或明確指定你的程式碼所支援型別的聯集(例如bytes | bytearray | memoryview)。ByteString最初被設計為一個抽象類別,以作為bytes和bytearray的超型別 (supertype)。然而由於 ABC 從未擁有任何方法,知道一個物件是ByteString的實例從未真正告訴你任何關於該物件的有用資訊。其他常見的緩衝區型別如memoryview也從未被理解為ByteString的子型別(無論是在 runtime 還是由靜態型別檢查器)。datetime:datetime.datetime的utcnow()和utcfromtimestamp()已棄用,並將在未來版本中刪除。請改用時區感知 (timezone-aware) 物件來表示 UTC 中的日期時間:分別呼叫now()和fromtimestamp()並將 tz 參數設定為datetime.UTC。(由 Paul Ganssle 在 gh-103857 中貢獻。)email:棄用email.utils.localtime()中的 isdst 參數。(由 Alan Williams 於 gh-72346 中貢獻。)importlib.abc:棄用下列類別,預定於 Python 3.14 中移除:importlib.abc.ResourceReaderimportlib.abc.Traversableimportlib.abc.TraversableResources
請改用
importlib.resources.abc類別:(由 Jason R. Coombs 和 Hugo van Kemenade 貢獻於 gh-93963。)
itertools:棄用對複製、深度複製和 pickle 操作的支援,這些操作沒有文件記錄、效率低下、過去常有錯誤且不一致。這將在 3.14 中刪除,以顯著地減少程式碼總量和維護負擔。(由 Raymond Hettinger 在 gh-101588 中貢獻。)multiprocessing:在 Python 3.14 中,預設的multiprocessing啟動方法將更改為 Linux、BSD 和其他非 macOS POSIX 平台上更安全的方法,其中'fork'目前是預設值 (gh-84559)。新增關於此的 runtime 警告被認為太具有破壞性,因為大多數程式碼預計不會關心它們。使用get_context()或set_start_method()API 明確指定你的程式碼何時需要'fork'。請參閱情境和啟動方法。pkgutil:pkgutil.find_loader()和pkgutil.get_loader()已被棄用並將在 Python 3.14 中移除;請改用importlib.util.find_spec()。(由 Nikita Sobolev 於 gh-97850 中貢獻。)pty:這個模組有兩個未記錄於文件中的函式master_open()和slave_open(),自 Python 2 以來已被棄用,但僅在 3.12 中會適時發出DeprecationWarning。將會在 3.14 中刪除它們。(由 Soumendra Ganguly 和 Gregory P. Smith 在 gh-85984 中貢獻。)os:Windows 上
os.stat()和os.lstat()回傳的st_ctime欄位已被棄用。在未來的版本中,它們將包含最近一次的元資料變更時間,與其他平台一致。目前它們仍然包含建立時間,這也可以在新的st_birthtime欄位中找到。(由 Steve Dower 在 gh-99726 中貢獻。)在 POSIX 平台上,當
os.fork()偵測到從多執行緒行程呼叫時,它現在可以引發DeprecationWarning。這樣做時始終存在與 POSIX 平台根本不相容的問題。即使這樣的程式碼看起來可以工作。我們新增了警告,以提高人們的認識,因為執行此操作的程式碼遇到的問題變得越來越頻繁。請參閱os.fork()文件以獲取更多詳細資訊,以及關於 fork 與執行緒不相容的討論了解為什麼我們現在向開發人員展示這個長期存在的平台相容性問題。
當由於使用
multiprocessing或concurrent.futures出現此警告時,修復方法是使用不同的multiprocessing啟動方法,例如"spawn"或"forkserver"。shutil:shutil.rmtree()的 onerror 引數已被棄用,請改用 onexc。(由 Irit Katriel 於 gh-102828 中貢獻。)-
預設適配器和轉換器現已棄用。請改為使用 Adapter and converter recipes 並根據你的需求進行細部調整。(由 Erlend E. Aasland 在 gh-90016 中貢獻。)
在
execute()中,當附名佔位符 (named placeholder) 與作為 sequence 提供的參數一起使用時,現在會發出DeprecationWarning而非作為dict。從 Python 3.14 開始,使用附名佔位符以及作為序列提供的參數將引發ProgrammingError。(由 Erlend E. Aasland 在 gh-101698 中貢獻。)
sys:sys.last_type、sys.last_value和sys.last_traceback欄位已被棄用。請改用sys.last_exc。(由 Irit Katriel 於 gh-102778 中貢獻。)tarfile:不推薦在不指定 filter 的情況下提取 tar 檔案,直到 Python 3.14 為止,此時'data'過濾器將成為預設過濾器。有關詳細資訊,請參閱 解壓縮篩選器。-
typing.Hashable和typing.Sized分別是collections.abc.Hashable和collections.abc.Sized的別名,已被棄用。(gh-94309)自 Python 3.9 起已被棄用的
typing.ByteString現在在使用時會發出DeprecationWarning。(由 Alex Waygood 於 gh-91896 中貢獻。)
xml.etree.ElementTree:這個模組現在在測試xml.etree.ElementTree.Element的真值時發出DeprecationWarning。之前,Python 實作發出了FutureWarning,而 C 實作什麼也沒發出。(由 Jacob Walls 在 gh-83122 中貢獻。)coroutine throw()、generator throw()和async generator throw的三引數簽名 (type, value, traceback) 已棄用,並且可能會在 Python 的未來版本中刪除。請改用這些函式的單引數版本。(由 Ofey Chan 在 gh-89874 中貢獻。)現在,當模組上的
__package__與__spec__.parent不同時,會引發DeprecationWarning(以前是ImportWarning)。(由 Brett Cannon 在 gh-65961 中貢獻。)在模組上設定
__package__或__cached__已被棄用,並且 Python 3.14 中的引入系統將不再設定或考慮該設定。(由 Brett Cannon 在 gh-65961 中貢獻。)bool 上的位元反轉運算子 (
~) 已棄用。在 Python 3.16 中它將拋出錯誤。使用not來代替布林值的邏輯否定。在極少數情況下,你確實需要對底層int進行位元反轉,請明確轉換為 int:~int(x)。(由 Tim Hoffmann 在 gh-103487 中貢獻。)自 3.10 起,於程式碼物件存取
co_lnotab的功能已在 PEP 626 中被棄用,但只在 3.12 中於適時發出DeprecationWarning。可能在 3.15 中移除。(由 Nikita Sobolev 於 gh-101866 貢獻。)
Python 3.13 中待移除的項目¶
模組(請見 PEP 594):
aifcaudioopcgicgitbchunkcryptimghdrmailcapmsilibnisnntplibossaudiodevpipessndhdrspwdsunautelnetlibuuxdrlib
其他模組:
lib2to3和 2to3 程式 (gh-84540)
API:
configparser.LegacyInterpolation(gh-90765)locale.resetlocale()(gh-90817)turtle.RawTurtle.settiltangle()(gh-50096)unittest.findTestCases()(gh-50096)unittest.getTestCaseNames()(gh-50096)unittest.makeSuite()(gh-50096)unittest.TestProgram.usageExit()(gh-67048)webbrowser.MacOSX(gh-86421)classmethod描述器鏈接 (gh-89519)
Python 3.14 中待移除的項目¶
argparse:argparse.BooleanOptionalAction的 type、choices 和 metavar 參數已被棄用,將在 3.14 中移除。(由 Nikita Sobolev 於 gh-92248 貢獻。)ast:自 Python 3.8 起,下列功能已在文件中被棄用,現在在存取或使用時會於 runtime 發出DeprecationWarning,並將在 Python 3.14 中移除:ast.Numast.Strast.Bytesast.NameConstantast.Ellipsis
請改用
ast.Constant。(由 Serhiy Storchaka 於 gh-90953 貢獻。)-
已棄用並將在 Python 3.14 中移除的 child watcher 類別:
asyncio.MultiLoopChildWatcher、asyncio.FastChildWatcher、asyncio.AbstractChildWatcher和asyncio.SafeChildWatcher。(由 Kumar Aditya 於 gh-94597 貢獻。)asyncio.set_child_watcher()、asyncio.get_child_watcher()、asyncio.AbstractEventLoopPolicy.set_child_watcher()和asyncio.AbstractEventLoopPolicy.get_child_watcher()已被棄用並將在 Python 3.14 中移除。(由 Kumar Aditya 於 gh-94597 貢獻。)預設事件迴圈策略的
get_event_loop()方法現在會在沒有設定目前事件迴圈且決定建立一個時發出DeprecationWarning。(由 Serhiy Storchaka 和 Guido van Rossum 於 gh-100160 貢獻。)
email:已棄用email.utils.localtime()中的 isdst 參數。(由 Alan Williams 於 gh-72346 貢獻。)importlib.abc的已棄用類別:importlib.abc.ResourceReaderimportlib.abc.Traversableimportlib.abc.TraversableResources
請改用
importlib.resources.abc類別:(由 Jason R. Coombs 和 Hugo van Kemenade 貢獻於 gh-93963。)
itertools有不以文件記錄、效率低下、過去常有 bug 且不一致的 copy、deepcopy 和 pickle 操作支援。將在 3.14 中移除以大幅減少程式碼量和維護負擔。(由 Raymond Hettinger 於 gh-101588 貢獻。)multiprocessing:預設的啟動方法將在 Linux、BSD 和其他非 macOS POSIX 平台上更改為更安全的方法,目前'fork'是預設值 (gh-84559)。對此增加一個 runtime 警告被認為太過擾人,因為 大多數程式碼不會在意。請使用get_context()或set_start_method()API 來明確指定你的程式碼何時需要'fork'。請參閱 Contexts and start methods。pathlib:已棄用is_relative_to()和relative_to():額外引數的傳遞已被棄用。pkgutil:pkgutil.find_loader()和pkgutil.get_loader()現在會引發DeprecationWarning;請改用importlib.util.find_spec()。(由 Nikita Sobolev 於 gh-97850 貢獻。)pty:master_open():請用pty.openpty()。slave_open():請用pty.openpty()。
-
version和version_info。execute()和executemany(),如果使用 named placeholders 且 parameters 是序列而不是dict。
urllib:urllib.parse.Quoter已被棄用:它並非預期的公開 API。(由 Gregory P. Smith 於 gh-88168 貢獻。)
Python 3.15 中待移除的項目¶
引入系統 (import system):
在模組上設定
__cached__而沒有設定__spec__.cached的做法已被棄用。在 Python 3.15 中,引入系統或標準函式庫將不再設定或考慮__cached__。(gh-97879)在模組上設定
__package__而沒有設定__spec__.parent的做法已被棄用。在 Python 3.15 中,引入系統或標準函式庫將不再設定或考慮__package__。(gh-97879)
-
自 Python 3.13 起,未記錄的
ctypes.SetPointerType()函式已被棄用。
-
過時且很少使用的
CGIHTTPRequestHandler自 Python 3.13 起已被棄用。不存在直接的替代。任何東西都比 CGI 更好地將 Web 伺服器與請求處理程序介接起來。自 Python 3.13 起,python -m http.server 命令列介面的
--cgi旗標已被棄用。
-
load_module()method:請改用exec_module()。
-
getdefaultlocale()已在 Python 3.11 中被棄用,原本計劃在 Python 3.13 中移除 (gh-90817),但被延後至 Python 3.15。請改用getlocale()、setlocale()和getencoding()。(由 Hugo van Kemenade 於 gh-111187 貢獻。)
-
PurePath.is_reserved()已自 Python 3.13 被棄用。請用os.path.isreserved()來偵測 Windows 上的保留路徑。
-
自 Python 3.13 起,
java_ver()已被棄用。此函式僅對 Jython 支援有用,具有令人困惑的 API,基本上未經測試。
-
sysconfig.is_python_build()的 check_home 引數自 Python 3.12 起已被棄用。
-
RLock()在 Python 3.15 中將不接受任何引數。自 Python 3.14 起,傳遞任何引數的用法已被棄用,因為 Python 版本不允許任何引數,但 C 版本允許任意數量的位置或關鍵字引數,並忽略每個引數。
-
types.CodeType:自 3.10 起,存取co_lnotab已在 PEP 626 中被棄用,並計劃在 3.12 中移除,但只在 3.12 中於適當時發出DeprecationWarning。可能在 3.15 中移除。(由 Nikita Sobolev 於 gh-101866 貢獻。)
-
用於建立
NamedTuple類別的未以文件記錄之關鍵字引數語法 (Point = NamedTuple("Point", x=int, y=int)) 已自 Python 3.13 棄用。請改用基於類別的語法或函式語法 (functional syntax)。當使用
TypedDict的函式語法時,未傳遞值給 fields 參數 (TD = TypedDict("TD")) 或傳遞None(TD = TypedDict("TD", None)) 的做法自 Python 3.13 起已被棄用。請使用class TD(TypedDict): pass或TD = TypedDict("TD", {})來建立具有零個欄位的 TypedDict。自 Python 3.13 起,
typing.no_type_check_decorator()裝飾器函式已被棄用。在typing模組中使用了八年之後,它尚未得到任何主要型別檢查器的支援。
wave:已棄用
Wave_read和Wave_write類別的getmark()、setmark()和getmarkers()方法自 Python 3.13 被棄用。
-
load_module()自 Python 3.10 被棄用。請改用exec_module()。(由 Jiahao Li 於 gh-125746 貢獻。)
Python 3.16 中待移除的項目¶
引入系統 (import system):
在模組上設定
__loader__而沒有設定__spec__.loader的做法將於 Python 3.16 被棄用。在 Python 3.16 中,引入系統或標準函式庫將不再設定或考慮__loader__。
-
自 Python 3.3 起,
'u'格式碼 (wchar_t) 在文件中已被棄用,自 Python 3.13 起在 runtime 已被棄用。請使用'w'格式碼 (Py_UCS4) 來取代 Unicode 字元。
-
asyncio.iscoroutinefunction()已被棄用並將在 Python 3.16 中移除;請改用inspect.iscoroutinefunction()。(由 Jiahao Li 和 Kumar Aditya 於 gh-122875 貢獻。)asyncio策略系統已被棄用並將在 Python 3.16 中移除。特別是以下類別和函式已被棄用:使用者應該使用
asyncio.run()或asyncio.Runner搭配 loop_factory 來使用所需的事件迴圈實作。例如在 Windows 上使用
asyncio.SelectorEventLoop:import asyncio async def main(): ... asyncio.run(main(), loop_factory=asyncio.SelectorEventLoop)
(由 Kumar Aditya 於 gh-127949 貢獻。)
-
自 Python 3.12 起,布林型別的位元反轉
~True或~False已被棄用,因為它會產生不預期且不直觀的結果(-2和-1)。使用not x代替布林值的邏輯否定。在極少數情況下,你需要對底層的整數進行位元反轉,請明確轉換為~int(x)(~int(x))。
-
自 Python 3.14 起,使用 function 或 sequence 關鍵字引數呼叫
functools.reduce()的 Python 實作已被棄用。
-
對具有 strm 引數的自訂日誌記錄處理函式的支援已被棄用,並計劃在 Python 3.16 中移除。請改用 stream 引數。(由 Mariusz Felisiak 於 gh-115032 貢獻。)
-
有效的副檔名以 '.' 開頭或對
mimetypes.MimeTypes.add_type()為空字串。未加點的副檔名已被棄用,並將在 Python 3.16 中引發ValueError。(由 Hugo van Kemenade 於 gh-75223 貢獻。)
-
自 Python 3.14 起,
ExecError例外已被棄用。自 Python 3.4 以來,它尚未被shutil中的任何函式使用,現在是RuntimeError的別名。
-
自 Python 3.14 起,
Class.get_methods方法已被棄用。
sys:自 Python 3.13 起,
_enablelegacywindowsfsencoding()函式已被棄用。請改用PYTHONLEGACYWINDOWSFSENCODING環境變數。
-
自 Python 3.14 起,
sysconfig.expand_makefile_vars()函式已被棄用。請改用sysconfig.get_paths()的vars引數。
-
自 Python 3.13 起,未以文件記錄和未被使用的
TarFile.tarfile屬性已被棄用。
Python 3.17 中待移除的項目¶
-
collections.abc.ByteString預計在 Python 3.17 中移除。使用
isinstance(obj, collections.abc.Buffer)來測試obj是否在 runtime 實作了緩衝區協定。在型別註解的使用中,請用Buffer或明確指定你的程式碼所支援型別的聯集(例如bytes | bytearray | memoryview)。ByteString最初被設計為一個抽象類別,以作為bytes和bytearray的超型別 (supertype)。然而由於 ABC 從未擁有任何方法,知道一個物件是ByteString的實例從未真正告訴你任何關於該物件的有用資訊。其他常見的緩衝區型別如memoryview也從未被理解為ByteString的子型別(無論是在 runtime 還是由靜態型別檢查器)。
-
在 Python 3.14 之前,舊式聯集是使用私有類別
typing._UnionGenericAlias實作的。這個類別不再被需要,但為了向後相容性而保留,並計劃將在 Python 3.17 中移除。使用者應該改用文件中記錄的內省輔助函式,例如typing.get_origin()和typing.get_args(),而非依賴私有實作細節。typing.ByteString自 Python 3.9 起已被棄用,預計在 Python 3.17 中移除。使用
isinstance(obj, collections.abc.Buffer)來測試obj是否在 runtime 實作了緩衝區協定。在型別註解的使用中,請用Buffer或明確指定你的程式碼所支援型別的聯集(例如bytes | bytearray | memoryview)。ByteString最初被設計為一個抽象類別,以作為bytes和bytearray的超型別 (supertype)。然而由於 ABC 從未擁有任何方法,知道一個物件是ByteString的實例從未真正告訴你任何關於該物件的有用資訊。其他常見的緩衝區型別如memoryview也從未被理解為ByteString的子型別(無論是在 runtime 還是由靜態型別檢查器)。
未來版本中的待移除項目¶
以下 API 將在未來被移除,雖然目前尚未安排移除日期。
-
巢狀引數群組和巢狀互斥群組已被棄用。
將未以文件記錄的關鍵字引數 prefix_chars 傳遞給
add_argument_group()的做法現在已被棄用。argparse.FileType型別轉換器已被棄用。
-
產生器:
throw(type, exc, tb)和athrow(type, exc, tb)簽名已被棄用:請改用throw(exc)和athrow(exc),為單引數簽名。目前 Python 接受數值字面值後面立即接關鍵字,例如
0in x、1or x、0if 1else 2。它讓運算式模糊且容易混淆,如[0x1for x in y](可以解釋為[0x1 for x in y]或[0x1f or x in y])。如果數值字面值後立即接and、else、for、if、in、is和or之一的關鍵字,則會引發語法警告。在未來版本中,它將被更改為語法錯誤。(gh-87999)__index__()和__int__()方法回傳非 int 型別的支援:這些方法將需要回傳int的嚴格子類別實例。回傳
float嚴格子類別__float__()方法的支援:這些方法將需要回傳float的實例。回傳
complex嚴格子類別__complex__()方法的支援:這些方法將需要回傳complex的實例。在
complex()建構子中將複數作為 real 或 imag 引數傳遞現在已被棄用;它應該只作為單個位置引數傳遞。(由 Serhiy Storchaka 於 gh-109218 貢獻。)
calendar:calendar.January和calendar.February常數已被棄用並被calendar.JANUARY和calendar.FEBRUARY取代。(由 Prince Roshan 於 gh-103636 貢獻。)codecs:請改用open()而非codecs.open()。(gh-133038)-
utcnow():請改用datetime.datetime.now(tz=datetime.UTC)。utcfromtimestamp():請改用datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)。
gettext:複數值必須是整數。-
cache_from_source()debug_override 參數已被棄用:請改用 optimization 參數。
-
EntryPoints元組介面。回傳值上的隱式
None。
mailbox:已棄用 StringIO 輸入和文字模式,請改用 BytesIO 和二進位模式。os:在多執行緒行程中呼叫os.register_at_fork()。pydoc.ErrorDuringImport:exc_info 參數的元組值已被棄用,請用例外實例。re:現在對正規表示式中的數值群組參照和群組名稱用了更嚴格的規則。現在只有 ASCII 數碼序列被接受作為數值參照。位元組模式和替換字串中的群組名稱現在只能包含 ASCII 字母、數碼和底線。(由 Serhiy Storchaka 於 gh-91760 貢獻。)sre_compile、sre_constants和sre_parse模組。shutil:rmtree()的 onerror 參數在 Python 3.12 中已被棄用;請改用 onexc 參數。ssl選項和協定:不帶協定引數的
ssl.SSLContext已被棄用。ssl.SSLContext:set_npn_protocols()和selected_npn_protocol()已被棄用:請改用 ALPN。ssl.OP_NO_SSL*選項ssl.OP_NO_TLS*選項ssl.PROTOCOL_SSLv3ssl.PROTOCOL_TLSssl.PROTOCOL_TLSv1ssl.PROTOCOL_TLSv1_1ssl.PROTOCOL_TLSv1_2ssl.TLSVersion.SSLv3ssl.TLSVersion.TLSv1ssl.TLSVersion.TLSv1_1
threading方法:threading.Condition.notifyAll():請用notify_all()。threading.Event.isSet():請用is_set()。threading.Thread.isDaemon()、threading.Thread.setDaemon():請用threading.Thread.daemon屬性。threading.Thread.getName()、threading.Thread.setName():請用threading.Thread.name屬性。threading.currentThread():請用threading.current_thread()。threading.activeCount():請用threading.active_count()。
內部類別
typing._UnionGenericAlias不再用於實作typing.Union。為了保持與此私有類別使用者的相容性,直到至少 Python 3.17 都將提供一個相容性 shim。(由 Jelle Zijlstra 於 gh-105499 貢獻。)unittest.IsolatedAsyncioTestCase:從測試案例中回傳非None的值已被棄用。urllib.parse已棄用函式:請改用urlparse()。splitattr()splithost()splitnport()splitpasswd()splitport()splitquery()splittag()splittype()splituser()splitvalue()to_bytes()
wsgiref:SimpleHandler.stdout.write()不應該進行部分寫入。xml.etree.ElementTree:已棄用對Element的真值測試。在未來版本中,它將始終回傳True。請改用明確的len(elem)或elem is not None測試。sys._clear_type_cache()已被棄用:請改用sys._clear_internal_caches()。
已移除¶
asynchat 和 asyncore¶
configparser¶
根據 gh-89336,已移除了在 3.2 中被
configparser棄用的幾個名稱:configparser.ParsingError不再具有filename屬性或引數。請改用source屬性和引數。configparser不再具有SafeConfigParser類別。請改用較短的ConfigParser名稱。configparser.ConfigParser不再具有readfp方法。請改用read_file()。
distutils¶
ensurepip¶
從
ensurepip中刪除綁定的 setuptools wheel,並停止在venv建立的環境中安裝 setuptools。pip (>= 22.1)不需要在環境中安裝 setuptools。基於setuptools(以及基於distutils)的套件仍然可以透過pip install來使用,因為 pip 會在其用於建置套件的建置環境中提供setuptools。以
venv建立或以ensurepip啟動引導的環境中不再預設提供easy_install、pkg_resources、setuptools和distutils,因為它們是setuptools套件的一部分。對於在 runtime 依賴這些工具的專案,應將setuptools專案宣告為相依套件並單獨安裝(通常使用 pip)。(由 Pradyun Gedam 於 gh-95299 中貢獻。)
enum¶
移除
enum的EnumMeta.__getattr__,對於列舉屬性的存取不再會需要它。
ftplib¶
gzip¶
移除
gzip的gzip.GzipFile的filename屬性(自 Python 2.6 起已棄用),改用name屬性。在寫入模式下,filename屬性會新增'.gz'檔案副檔名(如果不存在)。(由 Victor Stinner 在 gh-94196 中貢獻。)
hashlib¶
刪除
hashlib的hashlib.pbkdf2_hmac()的純 Python 實作(在 Python 3.10 中已棄用)。Python 3.10 及更新版本需要 OpenSSL 1.1.1 (PEP 644):此 OpenSSL 版本提供了更快的pbkdf2_hmac()的 C 實作。(由 Victor Stinner 在 gh-94199 中貢獻。)
importlib¶
現已完成清理
importlib中許多過去已經棄用的東西:對
module_repr()的參照和支援已刪除。(由 Barry Warsaw 在 gh-97850 中貢獻。)importlib.util.set_package、importlib.util.set_loader和importlib.util.module_for_loader已全部刪除。(由 Brett Cannon 和 Nikita Sobolev 在 gh-65961 和 gh-97850 貢獻。)對
find_loader()和find_module()API 的支援已被刪除。(由 Barry Warsaw 在 gh-98040 中貢獻。)importlib.abc.Finder、pkgutil.ImpImporter和pkgutil.ImpLoader已被刪除。(由 Barry Warsaw 在 gh-98040 中貢獻。)
imp¶
imp模組已被移除。(由 Barry Warsaw 在 gh-98040 中貢獻。)要遷移的話請參考以下對應表:
imp
importlib
imp.NullImporter將
None插入sys.path_importer_cacheimp.cache_from_source()imp.find_module()imp.get_magic()imp.get_suffixes()importlib.machinery.SOURCE_SUFFIXES、importlib.machinery.EXTENSION_SUFFIXES和importlib.machinery.BYTECODE_SUFFIXESimp.get_tag()imp.load_module()imp.new_module(name)types.ModuleType(name)imp.reload()imp.source_from_cache()imp.load_source()見下文
用以下取代
imp.load_source():import importlib.util import importlib.machinery def load_source(modname, filename): loader = importlib.machinery.SourceFileLoader(modname, filename) spec = importlib.util.spec_from_file_location(modname, filename, loader=loader) module = importlib.util.module_from_spec(spec) # 此模組都會被執行且不會被快取於 sys.modules。 # 要快取模組的話可以把下面一行取消註解 # sys.modules[module.__name__] = module loader.exec_module(module) return module
移除
imp函式和屬性、沒有替代方案:未以文件記錄的函式:
imp.init_builtin()imp.load_compiled()imp.load_dynamic()imp.load_package()
imp.lock_held()、imp.acquire_lock()、imp.release_lock():鎖定 scheme 在 Python 3.3 中已改為模組鎖 (per-module locks)。imp.find_module()常數:SEARCH_ERROR、PY_SOURCE、PY_COMPILED、C_EXTENSION、PY_RESOURCE、PKG_DIRECTORY、C_BUILTIN、PY_FROZEN、PY_CODERESOURCE、IMP_HOOK。
io¶
locale¶
刪除
locale的locale.format()函式(在 Python 3.7 中已棄用):請改用locale.format_string()。(由 Victor Stinner 在 gh-94226 中貢獻。)
smtpd¶
sqlite3¶
ssl¶
移除
ssl的ssl.RAND_pseudo_bytes()函式,該函式自 Python 3.6 起已被棄用:請改用os.urandom()或ssl.RAND_bytes()。(由 Victor Stinner 於 gh-94199 中貢獻。)移除
ssl.match_hostname()函式。該函式自 Python 3.7 起已被棄用。自 Python 3.7 起,OpenSSL 會執行主機名稱比對,Python 不再使用ssl.match_hostname()函式。(由 Victor Stinner 於 gh-94199 中貢獻。)移除
ssl.wrap_socket()函式,該函式自 Python 3.7 起已被棄用:請改為建立一個ssl.SSLContext物件並呼叫其ssl.SSLContext.wrap_socket方法。任何仍在使用ssl.wrap_socket()的套件都是有問題且不安全的。該函式既不傳送 SNI TLS 擴充,也不驗證伺服器主機名稱。程式碼會受到 CWE 295(不當的憑證驗證)影響。(由 Victor Stinner 於 gh-94199 中貢獻。)
unittest¶
移除許多
unittest中被棄用已久的功能:許多
TestCase方法別名:已棄用的別名
方法名稱
已棄用於
failUnless3.1
failIf3.1
failUnlessEqual3.1
failIfEqual3.1
failUnlessAlmostEqual3.1
failIfAlmostEqual3.1
failUnlessRaises3.1
assert_3.2
assertEquals3.2
assertNotEquals3.2
assertAlmostEquals3.2
assertNotAlmostEquals3.2
assertRegexpMatches3.2
assertRaisesRegexp3.2
assertNotRegexpMatches3.5
你可以使用 https://github.com/isidentical/teyit 來自動現代化你的單元測試。
未以文件記錄且已失效的
TestCase方法assertDictContainsSubset(自 Python 3.2 起已棄用)。未記錄的
TestLoader.loadTestsFromModule參數 use_load_tests(自 Python 3.5 起已棄用並忽略)。對
TextTestResult類別的別名:_TextTestResult(自 Python 3.2 起已棄用)。
(由 Serhiy Storchaka 於 gh-89325 中貢獻。)
webbrowser¶
從
webbrowser中刪除對過時瀏覽器的支援。刪除的瀏覽器包括:Grail、Mosaic、Netscape、Galeon、Skipstone、Iceape、Firebird 和 Firefox 版本 35 及以下 (gh-102871)。
xml.etree.ElementTree¶
刪除純 Python 實作的
ElementTree.Element.copy()方法(在 Python 3.10 中已棄用),改用copy.copy()函式。xml.etree.ElementTree的 C 實作沒有copy()方法,只有__copy__()方法。(由 Victor Stinner 在 gh-94383 中貢獻。)
zipimport¶
其他¶
從文件
Makefile和Doc/tools/rstlint.py中刪除suspicious規則,兩者皆改用 sphinx-lint。(由 Julien Palard 在 gh-98179 中貢獻。)從
ftplib、imaplib、poplib和smtplib模組中刪除 keyfile 和 certfile 參數,並刪除http.client模組中的 key_file、cert_file 和 check_hostname 參數,它們自 Python 3.6 起均已棄用。請使用 context 參數(imaplib中的 ssl_context)。(由 Victor Stinner 在 gh-94172 中貢獻。)移除數個標準函式庫模組與測試中的
Jython相容性修補程式。(由 Nikita Sobolev 於 gh-99482 中貢獻。)移除
ctypes模組中的_use_broken_old_ctypes_structure_semantics_旗標。(由 Nikita Sobolev 於 gh-99285 中貢獻。)
移植至 Python 3.12¶
本節列出了前面描述的變更以及可能需要你更改程式碼的其他錯誤修復。
Python API 的變更¶
現在,正規表示式中的數字群組參照和組名稱應用了更嚴格的規則。現在僅接受 ASCII 數字序列作為數字參考。位元組模式和替換字串中的組名稱現在只能包含 ASCII 字母、數字和底線。(由 Serhiy Storchaka 在 gh-91760 中貢獻。)
刪除自 Python 3.10 以來已棄用的
randrange()功能。以前randrange(10.0)無損轉換為randrange(10)。現在它會引發TypeError。此外,針對非整數值(例如randrange(10.5)或randrange('10'))引發的例外已從ValueError變更為TypeError。這也可以防止randrange(1e25)靜默地從比randrange(10**25)更大的範圍中進行選擇的錯誤。(最初由 Serhiy Storchaka 建議 gh-86388。)argparse.ArgumentParser更改了編碼和錯誤處理程式,用於從檔案(例如fromfile_prefix_chars選項)用預設文字編碼(例如locale.getpreferredencoding(False))中讀取引數到檔案系統編碼和錯誤處理程式。在 Windows 上,引數檔案應使用 UTF-8 編碼,而不是 Windows 的 ANSI Codepage。刪除 Python 3.4.7 和 3.5.4 中已棄用的基於
asyncore的smtpd模組。推薦的替代品是基於asyncio的 aiosmtpd PyPI 模組。shlex.split():以None做為 s 引數傳遞現在會引發例外,而不是讀取sys.stdin。該功能在 Python 3.9 中已被棄用。(由 Victor Stinner 在 gh-94352 中貢獻。)os模組不再接受類位元組的路徑,例如bytearray和memoryview型別:對於位元組字串,僅接受確切的bytes型別。(由 Victor Stinner 在 gh-98393 中貢獻。)如果在子直譯器中使用,
syslog.openlog()和syslog.closelog()現在會失敗。syslog.syslog()仍可在子直譯器中使用,但現在僅當syslog.openlog()已在主直譯器中呼叫。這些新限制不適用於主直譯器,因此只有極少數使用者可能會受到影響。此更改有助於直譯器隔離。此外,syslog是行程全域資源的包裝器,最好透過主直譯器進行管理。(由 Donghee Na 在 gh-99127 中貢獻。)未記錄於文件的
cached_property()鎖定行為已被刪除,因為它鎖定了類別的所有實例,從而導致高鎖定爭用 (high lock contention)。這意味著,如果兩個執行緒競爭,快取的屬性 getter 函式現在可以為單個實例運行多次。對於大多數簡單的快取屬性(例如,那些冪等屬性並且簡單地根據實例的其他屬性計算值),這將沒問題。如果需要同步,請在快取的屬性 getter 函式內或多執行緒存取點周圍實作鎖定。sys._current_exceptions()現在回傳從執行緒 id 到例外實例的對映,而不是(typ, exc, tb)元組。(由 Irit Katriel 在 gh-103176 中貢獻。)使用
tarfile或shutil.unpack_archive()提取 tar 檔案時,請傳遞 filter 引數以限制可能不預期或甚至危險的功能。詳細資訊請參閱 解壓縮篩選器。由於 PEP 701 中引入的更改,
tokenize.tokenize()和tokenize.generate_tokens()函式的輸出現已更改。這意味著不再為 f 字串發出STRING標記,並且現在產生 PEP 701 中描述的標記:FSTRING_START、FSTRING_MIDDLE和FSTRING_END除了運算式元件中用於標記化的適當標記之外,現在還會針對 f 字串 "string" 部分發出。例如,對於 f 字串f"start {1+1} end"舊版的標記產生器發出:1,0-1,18: STRING 'f"start {1+1} end"'
而新版本會發出:
1,0-1,2: FSTRING_START 'f"' 1,2-1,8: FSTRING_MIDDLE 'start ' 1,8-1,9: OP '{' 1,9-1,10: NUMBER '1' 1,10-1,11: OP '+' 1,11-1,12: NUMBER '1' 1,12-1,13: OP '}' 1,13-1,17: FSTRING_MIDDLE ' end' 1,17-1,18: FSTRING_END '"'
此外,由於支援 PEP 701 所做的更改,可能會出現一些細微的行為變化。其中的變化包括:
對某些無效 Python 字元(例如
!)進行標記時發出的標記的type屬性已從ERRORTOKEN更改為OP。不完整的單列字串現在也會像不完整的多列字串一樣引發
tokenize.TokenError。一些不完整或無效的 Python 程式碼現在會引發
tokenize.TokenError,而不是在 tokenize 時回傳任意ERRORTOKEN標記。不再支援在同一檔案中混合 Tab 字元和空格作為縮排,並且會引發
TabError。
threading模組現在期望_thread模組具有_is_main_interpreter屬性。它是一個沒有引數的函式,如果目前直譯器是主直譯器,則回傳True。任何提供自訂
_thread模組的函式庫或應用程式都應該提供_is_main_interpreter()。(參閱 gh-112826。)
建置變更¶
Python 不再使用
setup.py來建立共享 C 擴充模組。在configure腳本中偵測到頭檔和函式庫等建置參數。擴充功能由Makefile建置。大多數擴充功能使用pkg-config並回退到手動檢測。(由 Christian Heimes 在 gh-93939 中貢獻。)現在建置 Python 需要帶有兩個參數的
va_start(),例如va_start(args, format),。va_start()不再以單個參數來被呼叫。(由 Kumar Aditya 在 gh-93207 中貢獻。)CPython 現在會使用 ThinLTO 選項作為預設連結時間最佳化策略(如果 Clang 編譯器接受該旗標)。(由 Donghee Na 在 gh-89536 中貢獻。)
在
Makefile中新增COMPILEALL_OPTS變數以覆蓋make install中的compileall選項(預設值:-j0)。也將 3 個compileall指令合併為一個指令,來一次性為所有最佳化等級(0、1、2)建置 .pyc 檔案。(由 Victor Stinner 在 gh-99289 中貢獻。)為 64 位元 LoongArch 新增平台三元組:
loongarch64-linux-gnusf
loongarch64-linux-gnuf32
loongarch64-linux-gnu
(由 Zhang Na 於 gh-90656 中貢獻。)
PYTHON_FOR_REGEN現在需要 Python 3.10 或更新的版本。現在需要 Autoconf 2.71 和 aclocal 1.16.4 來重新產生
configure。(由 Christian Heimes 在 gh-89886 中貢獻。)來自 python.org 的 Windows 建置和 macOS 安裝程式現在使用 OpenSSL 3.0。
C API 變更¶
新增功能¶
PEP 697:引入 不穩定 C API 層,設計用於偵錯器和 JIT 編譯器等低階工具。此 API 可能會在 CPython 的每個次要版本中發生更改,而不會出現棄用警告。其內容由名稱中的
PyUnstable_前綴標記。程式碼物件建構函式:
PyUnstable_Code_New()(自PyCode_New重新命名)PyUnstable_Code_NewWithPosOnlyArgs()(自PyCode_NewWithPosOnlyArgs重新命名)
程式碼物件的額外儲存 (PEP 523):
PyUnstable_Eval_RequestCodeExtraIndex()(自_PyEval_RequestCodeExtraIndex重新命名)PyUnstable_Code_GetExtra()(自_PyCode_GetExtra重新命名)PyUnstable_Code_SetExtra()(自_PyCode_SetExtra重新命名)
原始名稱將可繼續使用,直到相應的 API 發生變更。
(由 Petr Viktorin 於 gh-101101 中貢獻。)
PEP 697:新增一個 API 用來擴充實例記憶體佈局不透明的型別:
PyType_Spec.basicsize可以為零或負數來指定繼承或擴充基底類別大小。新增了
PyObject_GetTypeData()和PyType_GetTypeDataSize()以允許存取特定於子類別的實例資料。新增了
Py_TPFLAGS_ITEMS_AT_END和PyObject_GetItemData()以允許安全地擴充某些可變大小的型別,包括PyType_Type。新增了
Py_RELATIVE_OFFSET以允許根據子類別特定的結構定義成員。
(由 Petr Viktorin 於 gh-103509 中貢獻。)
新增新的受限 C API 函式
PyType_FromMetaclass(),它使用附加元類別參數來概括現有的PyType_FromModuleAndSpec()。(由 Wenzel Jakob 在 gh-93012 中貢獻。)用於建立可使用向量呼叫協定進行呼叫的物件的 API 已新增到 有限 API 中:
現在,當重新分配類別的
__call__()方法時,Py_TPFLAGS_HAVE_VECTORCALL旗標將從類中刪除。這使得 vectorcall 可以安全地與可變型別一起使用(即沒有不可變旗標的堆型別,Py_TPFLAGS_IMMUTABLETYPE)。不覆蓋tp_call的可變型別現在繼承Py_TPFLAGS_HAVE_VECTORCALL旗標。(由 Petr Viktorin 在 gh-93274 中貢獻。)新增了
Py_TPFLAGS_MANAGED_DICT和Py_TPFLAGS_MANAGED_WEAKREF旗標。這允許擴充類別以更少的簿記 (bookkeeping)、使用更少的記憶體和更快的存取來支援物件__dict__和 weakrefs。使用向量呼叫協定執行呼叫的 API 已新增到有限 API 中:
這意味著向量呼叫協定的傳入和傳出端現在都可以在受限 API 中使用。(由 Wenzel Jakob 在 gh-98586 中貢獻。)
新增兩個公開函式
PyEval_SetProfileAllThreads()和PyEval_SetTraceAllThreads(),它們允許在除呼叫執行緒之外的所有正在執行的執行緒中設定追蹤和分析函式。(由 Pablo Galindo 在 gh-93503 中貢獻。)將新函式
PyFunction_SetVectorcall()新增至 C API,用於設定給定PyFunctionObject的向量呼叫欄位。(由 Andrew Frost 在 gh-92257 中貢獻。)C API 現在允許透過
PyDict_AddWatcher()、PyDict_Watch()註冊回呼以及每當修改字典時呼叫的相關 API。它旨在供最佳化直譯器、JIT 編譯器或偵錯器使用。(由 Carl Meyer 在 gh-91052 中貢獻。)新增
PyType_AddWatcher()和PyType_Watch()API 來註冊回呼以接收有關型別變更的通知。(由 Carl Meyer 在 gh-91051 貢獻。)新增
PyCode_AddWatcher()和PyCode_ClearWatcher()API 來註冊回呼以接收有關建立和銷毀程式碼物件的通知。(由 Itamar Oren 在 gh-91054 中貢獻。)新增
PyFrame_GetVar()和PyFrame_GetVarString()函式以透過名稱獲取 frame 變數。(由 Victor Stinner 在 gh-91248 中貢獻。)新增
PyErr_GetRaisedException()和PyErr_SetRaisedException()以用於儲存和復原目前的例外。這些函式回傳並接受單一例外物件,而非現已棄用的PyErr_Fetch()和PyErr_Restore()的三元引數。這樣做較不容易出錯且效率稍高。(由 Mark Shannon 於 gh-101578 中貢獻。)新增
_PyErr_ChainExceptions1,它接受一個例外實例,以取代現已棄用的舊版 API_PyErr_ChainExceptions。(由 Mark Shannon 於 gh-101578 中貢獻。)新增
PyException_GetArgs()和PyException_SetArgs()作為便捷函式,用於取得和修改傳遞給例外建構函式的args。(由 Mark Shannon 於 gh-101578 中貢獻。)新增
PyErr_DisplayException(),它接受一個例外實例,以取代舊版 APIPyErr_Display()。(由 Irit Katriel 於 gh-102755 中貢獻。)
PEP 683:引入不滅物件,它允許物件繞過參照計數,以及對 C-API 的相關變更:
_Py_IMMORTAL_REFCNT:定義物件的參照計數為不滅的。
_Py_IsImmortal檢查物件是否具有不滅參照計數。PyObject_HEAD_INIT這現在將初始化參照計數_Py_IMMORTAL_REFCNT(與Py_BUILD_CORE一起使用時)。
SSTATE_INTERNED_IMMORTAL駐留的 (interned) unicode 物件的識別字那是不滅的。
SSSTATE_INTERNED_IMMORTAL_STATIC駐留的 unicode 的識別字不滅且靜態的物件
sys.getunicodeinternedsize這會回傳 unicode 的總數已駐留的物件。現在
refleak.py需要這個來正確追蹤參照計數和分配的區塊
(由 Eddie Elizondo 於 gh-84436 中貢獻。)
PEP 684:新增新的
Py_NewInterpreterFromConfig()函式和PyInterpreterConfig,它們可用於建立具有自己的 GIL 的子直譯器。(有關更多資訊,請參閱 PEP 684:直譯器各別持有的 GIL。)(由 Eric Snow 在 gh-104110 中貢獻。)在受限 C API 版本 3.12 中,
Py_INCREF()和Py_DECREF()函式現在被實作為不透明函式呼叫,以隱藏實作細節。(由 Victor Stinner 在 gh-105387 中貢獻。)
移植至 Python 3.12¶
基於
Py_UNICODE*表示的舊版 Unicode API 已被刪除。請遷移到基於 UTF-8 或wchar_t*的 API。像
PyArg_ParseTuple()這樣的參數剖析函式不再支援基於Py_UNICODE*的格式(例如u,Z)。請遷移到其他 Unicode 格式,例如s、z、es和U。所有靜態內建型別的
tp_weaklist始終為NULL。這是PyTypeObject上的一個僅限內部的欄位,但我們指出了這一變更,以防有人碰巧直接存取該欄位。為了避免損壞,請考慮使用現有的公開 C-API,或者,如有必要,使用(僅限內部)_PyObject_GET_WEAKREFS_LISTPTR()巨集。這個僅限內部的
PyTypeObject.tp_subclasses現在可能不是有效的物件指標。它的型別已更改為 void* 以反映這一點。我們提到這一點是為了防止有人碰巧直接存取僅限內部的欄位。要獲取子類別串列,請呼叫 Python 方法
__subclasses__()(例如,使用PyObject_CallMethod())。在
PyUnicode_FromFormat()和PyUnicode_FromFormatV()中新增對更多格式化選項的支援(左對齊、八進制、大寫十六進位、intmax_t、ptrdiff_t、wchar_tC 字串、可變寬度和精度)。(由 Serhiy Storchaka 在 gh-98836 中貢獻。)PyUnicode_FromFormat()和PyUnicode_FromFormatV()中無法識別的格式字元現在會設定SystemError。在以前的版本中,它導致格式字串的所有其餘部分按原樣複製到結果字串,並丟棄任何額外的參數。(由 Serhiy Storchaka 在 gh-95781 中貢獻。)修正
PyUnicode_FromFormat()和PyUnicode_FromFormatV()中錯誤的符號位置。(由 Philip Georgi 在 gh-95504 中貢獻。)想要新增
__dict__或弱參照 (weak reference) 插槽的擴充類別應分別使用Py_TPFLAGS_MANAGED_DICT和Py_TPFLAGS_MANAGED_WEAKREF,而非tp_dictoffset和tp_weaklistoffset。tp_dictoffset和tp_weaklistoffset的使用仍受支援,但無法完全支援多重繼承 (gh-95589),且效能可能較差。宣告Py_TPFLAGS_MANAGED_DICT的類別必須呼叫_PyObject_VisitManagedDict()和_PyObject_ClearManagedDict()來走訪和清除其實例的字典。若要清除弱參照,請如同之前一樣呼叫PyObject_ClearWeakRefs()。PyUnicode_FSDecoder()函式不再接受類似位元組的路徑,例如bytearray和memoryview型別:對於位元組字串,僅接受確切的bytes型別。(由 Victor Stinner 在 gh-98393 中貢獻。)Py_CLEAR、Py_SETREF和Py_XSETREF巨集現在僅計算其引數一次。如果引數有副作用,這些副作用將不再重複。(由 Victor Stinner 在 gh-98724 中貢獻。)直譯器的錯誤指示器現在總是標準化的。這意味著
PyErr_SetObject()、PyErr_SetString()和其他設定錯誤指示器的函式現在會在儲存例外之前對其進行規範化。(由 Mark Shannon 在 gh-101578 中貢獻。)_Py_RefTotal不再具有權威性,只是為了 ABI 相容性而保留。請注意,它是內部全域的,僅在偵錯版本中可用。如果你碰巧正在使用它,那麼你需要開始使用_Py_GetGlobalRefTotal()。現在,以下函式為新建立的型別選擇適當的元類別:
建立元類別覆蓋
tp_new的類別已被棄用,並且在 Python 3.14+ 中將被禁止。請注意,這些函式忽略元類別的tp_new,可能允許不完整的初始化。請注意,
PyType_FromMetaclass()(在 Python 3.12 中新增)已經不允許建立其元類別覆蓋tp_new(Python 中的__new__())的類別別。由於
tp_new幾乎覆蓋了PyType_From*函式所做的一切,因此兩者彼此不相容。現有的行為(在型別建立的幾個步驟中忽略元類別)通常是不安全的,因為(元)類別假設tp_new有被呼叫。沒有簡單的通用解決方法。以下其中一項可能適合你:如果你控制元類別,請避免在其中使用
tp_new:如果可以跳過初始化,則可以在
tp_init中完成。如果元類別不需要從 Python 實例化,請使用
Py_TPFLAGS_DISALLOW_INSTANTIATION旗標將其tp_new設定為NULL。這使得PyType_From*函式能夠接受。
避免使用
PyType_From*函式:如果你不需要特定於 C 的功能(插槽 (slot) 或設定實例大小),請透過呼叫元類別來建立型別。如果你知道可以安全地跳過
tp_new,請使用 Python 中的warnings.catch_warnings()過濾掉棄用警告。
PyOS_InputHook和PyOS_ReadlineFunctionPointer不再在子直譯器 (subinterpreter) 中呼叫。這是因為客戶端通常依賴於行程範圍的全域狀態(因為這些回呼無法恢復擴充模組狀態)。這也避免了擴充可能發現自己在它們不支援(或尚未載入)的子直譯器中運行的情況。請參閱 gh-104668 了解更多資訊。
PyLongObject已更改其內部結構以獲得更好的效能。儘管PyLongObject的內部是私有的,但它們被一些擴充模組使用。不應再直接存取內部欄位,而應使用以PyLong_...開頭的 API 函式。提供了兩個新的不穩定 API 函式,用於有效存取適合單一機器字的PyLongObject的值:透過
PyMem_SetAllocator()設定的自訂分配器現在要求是執行緒安全的,無論記憶體域如何。沒有自己狀態的分配器(包括 "hooks")不受影響。如果你的自訂分配器還不是執行緒安全的並且你需要指導,請建立一個新的 GitHub 問題並抄送@ericsnowcurrently。
已棄用¶
根據 PEP 699,
PyDictObject中的ma_version_tag欄位對於擴充模組已被棄用。存取該欄位將在編譯時生成編譯器警告。該欄位將在 Python 3.14 中刪除。(由 Ramvikrams 和 Kumar Aditya 在 gh-101193 中貢獻。PEP 為 Ken Jin 所撰寫。)棄用全域配置變數:
Py_HashRandomizationFlag:請改用PyConfig.use_hash_seed和PyConfig.hash_seedPy_LegacyWindowsFSEncodingFlag:請改用PyPreConfig.legacy_windows_fs_encodingPy_FileSystemDefaultEncoding:請改用PyConfig.filesystem_encodingPy_HasFileSystemDefaultEncoding:請改用PyConfig.filesystem_encodingPy_FileSystemDefaultEncodeErrors:請改用PyConfig.filesystem_errorsPy_UTF8Mode:請改用PyPreConfig.utf8_mode(參見Py_PreInitialize())
Py_InitializeFromConfig()API 應改為與PyConfig一起使用。(由 Victor Stinner 於 gh-77782 中貢獻。)structmember.h標頭已棄用,但仍可使用,且還沒有移除它的計畫。現在只需包含
Python.h即可使用其內容,如果缺少,則新增Py前綴:型別巨集,如
Py_T_INT、Py_T_DOUBLE等(以前為T_INT、T_DOUBLE等)Py_READONLY(先前為READONLY)和Py_AUDIT_READ(先前全大寫)旗標
數個項目不再從
Python.h中公開:T_OBJECT(請改用Py_T_OBJECT_EX)T_NONE(先前未記錄於文件上,且相當古怪)不做任何事的巨集
WRITE_RESTRICTED。RESTRICTED和READ_RESTRICTED這兩個巨集,相當於Py_AUDIT_READ。在某些配置中,
Python.h中不包含<stddef.h>。使用offsetof()時應手動包含它。
已棄用的標頭繼續以原始名稱提供其原始內容。你的舊程式碼可以保持不變,除非額外的包含巨集和非命名空間巨集對你造成很大困擾。
(由 Petr Viktorin 在 gh-47146 中貢獻,其基於 Alexander Belopolsky 和 Matthias Braun 的前期工作。)
PyErr_Fetch()和PyErr_Restore()已棄用。請改用PyErr_GetRaisedException()和PyErr_SetRaisedException()。(由 Mark Shannon 在 gh-101578 中貢獻。)PyErr_Display()已棄用,請改用PyErr_DisplayException()。(由 Irit Katriel 於 gh-102755 中貢獻。)_PyErr_ChainExceptions已棄用,請改用_PyErr_ChainExceptions1。(由 Irit Katriel 於 gh-102192 中貢獻。)使用
PyType_FromSpec()、PyType_FromSpecWithBases()或PyType_FromModuleAndSpec()建立一個其元類別覆寫tp_new的類別已被棄用。請改為呼叫元類別。
Python 3.14 中待移除的項目¶
PyDictObject中的ma_version_tag欄位,用於擴充模組 (PEP 699;gh-101193)。
Python 3.15 中待移除的項目¶
PyWeakref_GetObject()和PyWeakref_GET_OBJECT():請改用PyWeakref_GetRef()。可以使用 pythoncapi-compat 專案來為 Python 3.12 和更早版本取得PyWeakref_GetRef()。Py_UNICODE型別與Py_UNICODE_WIDE巨集:請改用wchar_t。PyUnicode_AsDecodedObject():請改用PyCodec_Decode()。PyUnicode_AsDecodedUnicode():請改用PyCodec_Decode();請注意某些編解碼器(例如 "base64")可能會回傳非str的型別,例如bytes。PyUnicode_AsEncodedObject():請改用PyCodec_Encode()。PyUnicode_AsEncodedUnicode():請改用PyCodec_Encode();請注意某些編解碼器(例如 "base64")可能會回傳非bytes的型別,例如str。Python 初始化函式,自 Python 3.13 起已被棄用:
Py_GetPath():請改用PyConfig_Get("module_search_paths")(sys.path)。Py_GetPrefix():請改用PyConfig_Get("base_prefix")(sys.base_prefix)。如果需要處理虛擬環境,請改用PyConfig_Get("prefix")(sys.prefix)。Py_GetExecPrefix():請改用PyConfig_Get("base_exec_prefix")(sys.base_exec_prefix)。如果需要處理虛擬環境,請改用PyConfig_Get("exec_prefix")(sys.exec_prefix)。Py_GetProgramFullPath():請改用PyConfig_Get("executable")(sys.executable)。Py_GetProgramName():請改用PyConfig_Get("executable")(sys.executable)。Py_GetPythonHome():請改用PyConfig_Get("home")或PYTHONHOME環境變數。
pythoncapi-compat 專案 可以用來為 Python 3.13 和更早版本取得
PyConfig_Get()。用於配置 Python 初始化的函式,自 Python 3.11 起已被棄用:
PySys_SetArgvEx():請改用PyConfig.argv。PySys_SetArgv():請改用PyConfig.argv。Py_SetProgramName():請改用PyConfig.program_name。Py_SetPythonHome():請改用PyConfig.home。PySys_ResetWarnOptions():請改為清除sys.warnoptions和warnings.filters。
應改用帶有
PyConfig的Py_InitializeFromConfig()API。全域配置變數:
Py_DebugFlag:請改用PyConfig.parser_debug或PyConfig_Get("parser_debug")。Py_VerboseFlag:請改用PyConfig.verbose或PyConfig_Get("verbose")。Py_InteractiveFlag:請改用PyConfig.interactive或PyConfig_Get("interactive")。Py_InspectFlag:請改用PyConfig.inspect或PyConfig_Get("inspect")。Py_OptimizeFlag:請改用PyConfig.optimization_level或PyConfig_Get("optimization_level")。Py_NoSiteFlag:請改用PyConfig.site_import或PyConfig_Get("site_import")。Py_BytesWarningFlag:請改用PyConfig.bytes_warning或PyConfig_Get("bytes_warning")。Py_FrozenFlag:請改用PyConfig.pathconfig_warnings或PyConfig_Get("pathconfig_warnings")。Py_IgnoreEnvironmentFlag:請改用PyConfig.use_environment或PyConfig_Get("use_environment")。Py_DontWriteBytecodeFlag:請改用PyConfig.write_bytecode或PyConfig_Get("write_bytecode")。Py_NoUserSiteDirectory:請改用PyConfig.user_site_directory或PyConfig_Get("user_site_directory")。Py_UnbufferedStdioFlag:請改用PyConfig.buffered_stdio或PyConfig_Get("buffered_stdio")。Py_HashRandomizationFlag:請改用PyConfig.use_hash_seed和PyConfig.hash_seed或PyConfig_Get("hash_seed")。Py_IsolatedFlag:請改用PyConfig.isolated或PyConfig_Get("isolated")。Py_LegacyWindowsFSEncodingFlag:請改用PyPreConfig.legacy_windows_fs_encoding或PyConfig_Get("legacy_windows_fs_encoding")。Py_LegacyWindowsStdioFlag:請改用PyConfig.legacy_windows_stdio或PyConfig_Get("legacy_windows_stdio")。Py_FileSystemDefaultEncoding、Py_HasFileSystemDefaultEncoding:請改用PyConfig.filesystem_encoding或PyConfig_Get("filesystem_encoding")。Py_FileSystemDefaultEncodeErrors:請改用PyConfig.filesystem_errors或PyConfig_Get("filesystem_errors")。Py_UTF8Mode:請改用PyPreConfig.utf8_mode或PyConfig_Get("utf8_mode")。(請參閱Py_PreInitialize())
應改用帶有
PyConfig的Py_InitializeFromConfig()API 來設定這些選項。或者也可以使用PyConfig_Get()在執行時取得這些選項。
Python 3.16 中待移除的項目¶
libmpdecimal的打包副本 (bundled copy)。
未來版本中的待移除項目¶
下列 API 已被棄用並將會被移除,不過目前尚未訂定移除日期。
Py_TPFLAGS_HAVE_FINALIZE:自 Python 3.8 起不再需要PySlice_GetIndicesEx():請改用PySlice_Unpack()和PySlice_AdjustIndices()。PyUnicode_READY():自 Python 3.12 起不再需要PyErr_Display():請改用PyErr_DisplayException()。_PyErr_ChainExceptions():請改用_PyErr_ChainExceptions1。PyBytesObject.ob_shash成員:請改為呼叫PyObject_Hash()。執行緒區域儲存 (Thread Local Storage, TLS) API:
已移除¶
移除
token.h標頭檔案。從未有任何公開的 tokenizer C API。token.h標頭檔案的設計是僅限用於 Python 內部。(由 Victor Stinner 於 gh-92651 中貢獻。)舊版 Unicode API 已被刪除。有關詳細資訊請參閱 PEP 623。
PyUnicode_WCHAR_KINDPyUnicode_AS_UNICODE()PyUnicode_AsUnicode()PyUnicode_AsUnicodeAndSize()PyUnicode_AS_DATA()PyUnicode_FromUnicode()PyUnicode_GET_SIZE()PyUnicode_GetSize()PyUnicode_GET_DATA_SIZE()
移除
PyUnicode_InternImmortal()函式巨集。(由 Victor Stinner 於 gh-85858 中貢獻。)