GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing python.github.io — Python 3.12 有什麼新功能 — Python 3.15.2 說明文件 Python 3.12 有什麼新功能¶
本文介紹了 Python 3.12 與 3.11 相比多了哪些新功能。Python 3.12 於 2023 年 10 月 2 日發布。完整詳情請見 changelog。 也參考 PEP 693 -- Python 3.12 發布時程 發布重點摘要¶Python 3.12 是 Python 程式語言的穩定版本,包含了語言和標準函式庫的綜合變更。標準函式庫的變更主要集中在清理棄用的 API、可用性和正確性。值得注意的是, 語言變更主要集中在可用性,因為 f-字串已經移除了許多限制,並且持續改進 'Did you mean ...' 建議。新的型別參數語法和 這篇文章並不試圖提供所有新功能的完整規格,而是提供一個方便的概覽。完整詳情應參考文件,如標準函式庫參考和語言參考。如果你想了解某個新功能的完整實作和設計理念,請參考該功能的 PEP;但請注意 PEP 通常在功能完全實作後就不再更新。 新增語法特性: 新增語法特性: 直譯器改進:
Python 資料模型改進: 標準函式庫中的顯著改進:
安全性改進:
C API 改進: CPython 實作改進:
新增型別特性: 重要的棄用、刪除或限制:
新增功能¶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 引入了一種使用 type Point = tuple[float, float] 型別別名也可以是泛型: type Point[T] = tuple[T, T] 新的語法允許宣告 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 轉義序列。讓我們詳細介紹一下這些內容:
詳情請見 PEP 701。 作為此功能實作方式的積極副作用(透過使用 PEG 剖析器 剖析 f 字串),現在 f 字串的錯誤訊息更加精確,並且包含錯誤的確切位置。例如,在 Python 3.11 中,以下 f 字串會引發 >>> 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 中提供。 使用新的 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 的更多範例,請參見 (由 Eric Snow 於 gh-104210 等貢獻。) PEP 669:CPython 的低影響監控¶PEP 669 定義了一個新的 (由 Mark Shannon 於 gh-103082 中貢獻。) PEP 688:使緩衝區協定可在 Python 中存取¶PEP 688 引入了一種從 Python 程式碼使用 緩衝區協定 的方法。實作 新的 PEP 709:行內綜合運算¶字典、串列和集合綜合運算現在是行內的,而不是為綜合運算的每次執行建立一個新的一次性函式物件。這可以將綜合運算的執行速度提高兩倍。請參閱 PEP 709 以了解更多詳細資訊。 綜合運算的疊代變數保持隔離,不會覆蓋外部作用域中的同名變數,綜合運算後它們也不可見。行內化確實會導致一些明顯的行為改變:
(由 Carl Meyer 和 Vladimir Matveev 於 PEP 709 中貢獻。) 改善錯誤訊息¶
型別提示相關的新特性¶PEP 692:使用
|
imp |
importlib |
|---|---|
|
將 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
見下文 |
用以下取代 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。
刪除 locale 的 locale.format() 函式(在 Python 3.7 中已棄用):請改用 locale.format_string()。(由 Victor Stinner 在 gh-94226 中貢獻。)
移除 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 中被棄用已久的功能:
許多 TestCase 方法別名:
已棄用的別名 |
方法名稱 |
已棄用於 |
|---|---|---|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.1 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.2 |
|
|
3.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 中刪除對過時瀏覽器的支援。刪除的瀏覽器包括:Grail、Mosaic、Netscape、Galeon、Skipstone、Iceape、Firebird 和 Firefox 版本 35 及以下 (gh-102871)。
刪除純 Python 實作的 ElementTree.Element.copy() 方法(在 Python 3.10 中已棄用),改用 copy.copy() 函式。xml.etree.ElementTree 的 C 實作沒有 copy() 方法,只有 __copy__() 方法。(由 Victor Stinner 在 gh-94383 中貢獻。)
從文件 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 中貢獻。)
本節列出了前面描述的變更以及可能需要你更改程式碼的其他錯誤修復。
現在,正規表示式中的數字群組參照和組名稱應用了更嚴格的規則。現在僅接受 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 中貢獻。)
未記錄於文件的 @~functools.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。
PEP 689: Introduce the Unstable C API tier,
intended for low-level tools like debuggers and JIT compilers.
This API may change in each minor release of CPython without deprecation
warnings.
Its contents are marked by the PyUnstable_ prefix in names.
程式碼物件建構函式:
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(),它接受一個例外實例,以取代舊版 API PyErr_Display()。(由 Irit Katriel 於 gh-102755 中貢獻。)
PEP 683:引入不滅物件,它允許物件繞過參照計數,以及對 C-API 的相關變更:
_Py_IMMORTAL_REFCNT: The reference count that defines an object
as immortal.
_Py_IsImmortal 檢查物件是否具有不滅參照計數。
PyObject_HEAD_INIT This will now initialize reference count to
_Py_IMMORTAL_REFCNT when used with Py_BUILD_CORE.
SSTATE_INTERNED_IMMORTAL An identifier for interned unicode objects
that are immortal.
SSTATE_INTERNED_IMMORTAL_STATIC An identifier for interned unicode
objects that are immortal and static
sys.getunicodeinternedsize This returns the total number of unicode
objects that have been interned. This is now needed for refleak.py to
correctly track reference counts and allocated blocks
(由 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 中貢獻。)
基於 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_t C 字串、可變寬度和精度)。(由 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_seed
Py_LegacyWindowsFSEncodingFlag:請改用 PyPreConfig.legacy_windows_fs_encoding
Py_FileSystemDefaultEncoding:請改用 PyConfig.filesystem_encoding
Py_HasFileSystemDefaultEncoding:請改用 PyConfig.filesystem_encoding
Py_FileSystemDefaultEncodeErrors:請改用 PyConfig.filesystem_errors
Py_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 的類別已被棄用。請改為呼叫元類別。
PyDictObject 中的 ma_version_tag 欄位,用於擴充模組 (PEP 699;gh-101193)。
The PyImport_ImportModuleNoBlock():
Use PyImport_ImportModule() instead.
PyWeakref_GetObject() and PyWeakref_GET_OBJECT():
Use PyWeakref_GetRef() instead. The pythoncapi-compat project can be used to get
PyWeakref_GetRef() on Python 3.12 and older.
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():
Use PyConfig_Get("module_search_paths")
(sys.path) instead.
Py_GetPrefix():
Use PyConfig_Get("base_prefix")
(sys.base_prefix) instead. Use PyConfig_Get("prefix") (sys.prefix) if virtual environments need to be handled.
Py_GetExecPrefix():
Use PyConfig_Get("base_exec_prefix")
(sys.base_exec_prefix) instead. Use
PyConfig_Get("exec_prefix")
(sys.exec_prefix) if virtual environments need to
be handled.
Py_GetProgramFullPath():
Use PyConfig_Get("executable")
(sys.executable) instead.
Py_GetProgramName():
Use PyConfig_Get("executable")
(sys.executable) instead.
Py_GetPythonHome():
Use PyConfig_Get("home") or the
PYTHONHOME environment variable instead.
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():
Clear sys.warnoptions and warnings.filters instead.
應改用帶有 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() 在執行時取得這些選項。
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_KIND
PyUnicode_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 中貢獻。)