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.11 有什麼新功能 — Python 3.15.2 說明文件 Python 3.11 有什麼新功能¶
此文章解釋了 Python 3.11 和 3.10 相比多了哪些新功能。Python 3.11 於 2022 年 10 月 24 日發布。完整細節請見 Changelog(更動日誌)。 發布重點摘要¶
新增語法特性: 新的內建功能: 新增標準函式庫模組: 直譯器的改進:
新增型別特性: 重要的棄用、移除與限制:
新增功能¶PEP 657:回溯 (traceback) 中更細緻的錯誤位置¶當要印出回溯,直譯器現在會指出造成錯誤的確切運算式,而非只說明是哪一行。例如: Traceback (most recent call last): File "distance.py", line 11, in <module> print(manhattan_distance(p1, p2)) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "distance.py", line 6, in manhattan_distance return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y) ^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'x' 前一版本的直譯器只會標明是哪一行,無法辨認哪一個物件是 Traceback (most recent call last): File "query.py", line 37, in <module> magic_arithmetic('foo') File "query.py", line 18, in magic_arithmetic return add_counts(x) / 25 ^^^^^^^^^^^^^ File "query.py", line 24, in add_counts return 25 + query_user(user1) + query_user(user2) ^^^^^^^^^^^^^^^^^ File "query.py", line 32, in query_user return 1 + query_count(db, response['a']['b']['c']['user'], retry=True) ~~~~~~~~~~~~~~~~~~^^^^^ TypeError: 'NoneType' object is not subscriptable 在複雜的計算運算式中也是: Traceback (most recent call last): File "calculation.py", line 54, in <module> result = (x / y / z) * (a / b / c) ~~~~~~^~~ ZeroDivisionError: division by zero 此外,強化回溯特性所使用的資訊可以透過一般的 API 來取得,以用來使 bytecode 指示 (instruction)與原始碼位置相互關聯。此項資訊可以用以下方式取得:
詳情請見 PEP 657。(由 Pablo Galindo、Batuhan Taskaya 與 Ammar Askar 於 bpo-43950 中所貢獻。) 備註 這個特性必須要將欄的位置 (column position) 儲存於 程式碼物件,這可能會導致直譯器用於編譯 Python 檔案的記憶體使用量與硬碟使用量增加。為了避免儲存多餘的資訊且停用印出多餘的回溯資訊,請用 PEP 654:例外群組與
|
操作 |
形式 |
特化 |
操作加速程度(上限) |
貢獻者 |
|---|---|---|---|---|
二元操作 |
|
10% |
Mark Shannon, Donghee Na, Brandt Bucher, Dennis Sweeney |
|
下標 |
|
下標容器型別如 下標自訂 |
10-25% |
Irit Katriel, Mark Shannon |
儲存下標 |
|
類似於上面的下標特化。 |
10-25% |
Dennis Sweeney |
呼叫 |
|
常見內建 (C) 函式和型別的呼叫,例如 |
20% |
Mark Shannon, Ken Jin |
載入全域變數 |
|
全域/內建之命名空間內的物件索引被快取起來。載入全域與內建變數不需要任何命名空間的查找。 |
Mark Shannon |
|
載入屬性 |
|
和載入全域變數類似,類別/物件之命名空間內的屬性索引被快取起來。在大部分情況中,載入屬性不需要任何命名空間的查找。 |
Mark Shannon |
|
載入要呼叫的方法 |
|
方法的真實記憶體地址被快取 (cache) 起來,方法的載入現在不需要命名空間的查找 -- 即便有很長繼承鏈結的類別也是。 |
10-20% |
Ken Jin, Mark Shannon |
儲存屬性 |
|
和載入屬性的最佳化相似。 |
2% 於 pyperformance 中 |
Mark Shannon |
拆解 (unpack) 序列 |
|
8% |
Brandt Bucher |
物件現在因為使用了惰性建立的物件命名空間所以需要更少的記憶體。它們的命名空間字典現在也更自由地共享鍵。(由 Mark Shannon 於 bpo-45340 和 bpo-40116 貢獻。 )
實作了「無代價 (Zero-cost)」的例外,消除了在沒有例外被引發時的 try 陳述式開銷。(由 Mark Shannon 於 bpo-40222 貢獻。)
在直譯器內使用更簡潔的例外表示法將捕獲一個例外所需的時間減少了大約 10%。 由 Irit Katriel 在 bpo-45711 中貢獻。)
re 的正規表示式比對引擎部分被重構,且現在會有支援的平台上使用 computed gotos(或者「執行緒程式碼 (threaded code)」),因此 Python 3.11 在執行 pyperformance 正規表示式基準量測的表現上比起 Python 3.10 快了 10%。(由 Brandt Bucher 於 gh-91404 中貢獻。)
撰寫符合 Python 風格 (Pythonic) 且依循常見最佳實踐的程式碼就好,你不需要改變你的程式碼。CPython 加速計畫中,我們為所觀察到的常見程式編寫模式來做最佳化。
也許不會。我們預期不會有超出 3.10 20% 的記憶體使用量。這數字會和上述禎物件與物件字典的記憶體最佳化而有所偏差。
某些程式中不會有顯著的好處。如果你的程式花了大部分的時間在 I/O 操作上,或已經將大部分計算用像是 numpy 的 C 擴充函式庫處理,那就不會有明顯的加速。這個計畫是對純 Python 的工作負荷最有幫助。
此外,pyperformance 數值為一個幾何平均數 (geometric mean)。即便在 pyperformance 基準量測中,某些測試稍微慢了一些,但其他加快了將近兩倍!
沒有,我們還在探索其他最佳化方式。
CPython 加速計畫探索了各種 CPython 最佳化的可能性。主要團隊由微軟 (microsoft) 所資助以全職發展該計畫,Pablo Galindo Salgado 亦由彭博有限合夥企業 (Bloomberg LP) 資助來兼職開發,更有許許多多來自社群的自發性貢獻者。
位元組碼現在包含行內快取條目,它們採用新添加的 CACHE 指示的形式。許多操作碼預期後面要有確切數量的快取,並指示直譯器在執行環境跳過它們。傳遞的 (populated) 快取看起來像任意指示,因此在讀取或修改包含加速資料的原始且適應 (adaptive) 位元組碼時應格外小心。
ASYNC_GEN_WRAP、RETURN_GENERATOR 和 SEND 被用於產生器與協程。
COPY_FREE_VARS,避免了為閉包 (closure) 而生的特殊呼叫方 (caller-side) 程式碼的需求。
JUMP_BACKWARD_NO_INTERRUPT,用於某些不需要處理中斷的循環。
CHECK_EG_MATCH 和 PREP_RERAISE_STAR,處理 PEP 654 所加入的新增例外群組和 except*。
PUSH_EXC_INFO 被用於例外處理函式。
RESUME,為無操作 (no-po),用於內部追查、除錯和最佳化檢查。
被取代的操作碼 |
新的操作碼 |
註記 |
|---|---|---|
BINARY_*INPLACE_* |
以單一一個操作碼來取代所有數值的、二進位/原位 (in-place) 操作碼 |
|
CALL_FUNCTIONCALL_FUNCTION_KWCALL_METHOD |
將方法的引數搬移 (argument shifting) 與關鍵字引數的處理分離開來;允許更好的呼叫特化 |
|
DUP_TOPDUP_TOP_TWOROT_TWOROT_THREEROT_FOURROT_N |
堆疊操作指示 |
|
JUMP_IF_NOT_EXC_MATCH |
現在執行檢查但不跳位 (jump) |
|
JUMP_ABSOLUTEPOP_JUMP_IF_FALSEPOP_JUMP_IF_TRUE |
參見 [3];每個方向的 |
|
SETUP_WITHSETUP_ASYNC_WITH |
|
|
所有跳位操作碼 (jump opcode) 現在都是相對的,包括現有的 JUMP_IF_TRUE_OR_POP 和 JUMP_IF_FALSE_OR_POP。該引數現在是目前指示 (instruction) 的偏移量而不是絕對位置。
更改了 MATCH_CLASS 和 MATCH_KEYS ,不再推送一個額外的布林值來表示成功/失敗。取而代之的是會在失敗時推送 None,而非一個包含提取值的元組。
更改了運作於例外的操作碼以反映它們現在在堆疊中的表示為一項而不是三項(請參閱 gh-89874)。
刪除 COPY_DICT_WITHOUT_KEYS、GEN_START、POP_BLOCK、SETUP_FINALLY 和 YIELD_FROM。
這個部分列出了在 Python 3.11 中棄用的 Python API。
被棄用的 C API 被獨立列出。
鏈接 classmethod 描述器(在 bpo-19072 中引入)現已棄用。它不能再用於包裝其他描述器,例如 property。此功能的核心設計存在缺陷,並導致了許多下游問題。要「傳遞通過 (pass-through)」classmethod,請考慮使用 Python 3.10 中添加的 __wrapped__ 屬性。(由 Raymond Hettinger 在 gh-89519 中貢獻。)
值大於 0o377(十進位為 255)的字串和位元組文本值 (bytes literal) 中的八進位跳脫 (octal escape) 現在會產生 DeprecationWarning。在未來的 Python 版本中,他們將引發一個 SyntaxWarning 並最終引發一個 SyntaxError。(由 Serhiy Storchaka 在 gh-81548 中貢獻。)
int() 到 __trunc__() 的授權 (delegation) 現已棄用。當 type(a) 有實作 __trunc__() 但沒有 __int__() 或 __index__(),呼叫 int(a) 現在會引發一個 DeprecationWarning。(由 Zackery Spytz 在 bpo-44977 中貢獻。)
PEP 594 引領下列模組的棄用,並排訂於 Python 3.13 移除:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(由 Brett Cannon 和 Victor Stinner 分別於 bpo-47061 與 gh-68966 中所貢獻。)
asynchat、asyncore 和 smtpd 至少在 Python 3.6 以前就被棄用,它們的文件與棄用警告現在已被更新為會提示它們即將於 Python 3.12 中移除。(由 Hugo van Kemenade 於 bpo-47022 中貢獻。)
:mod:!lib2to3` 套件和 2to3 工具現已棄用,可能無法剖析 Python 3.10 或更新版本。有關詳細資訊請參閱 PEP 617,它引入了新的 PEG 剖析器。(由 Victor Stinner 在 bpo-40360 中貢獻。)
未被記錄於文件中的 sre_compile、sre_constants 和 sre_parse 模組現在已被棄用。(由 Serhiy Storchaka 在 bpo-47152 中貢獻。)
以下 configparser 相關項目已在 Python 3.2 中棄用,它們的棄用警告現在會提示它們即將於 Python 3.12 中移除:
configparser.SafeConfigParser 類別
configparser.ParsingError.filename 屬性
configparser.RawConfigParser.readfp() 方法
(由 Hugo van Kemenade 於 bpo-45173 中所貢獻。)
configparser.LegacyInterpolation 自 Python 3.2 起已在文件字串中棄用,並且未在 configparser 文件中列出。它現在會發出一個 DeprecationWarning 並將在 Python 3.13 中刪除。請改用 configparser.BasicInterpolation 或 configparser.ExtendedInterpolation。(由 Hugo van Kemenade 在 bpo-46607 中貢獻。)
舊的 importlib.resources 函式集因為不支援定位套件子目錄中的資源而被棄用、並將在未來的 Python 版本中刪除,取而代之的是在 Python 3.9 中添加的替代方案:
importlib.resources.contents()
importlib.resources.is_resource()
importlib.resources.open_binary()
importlib.resources.open_text()
importlib.resources.read_binary()
importlib.resources.read_text()
importlib.resources.path()
locale.getdefaultlocale() 函式已被棄用且將於 Python 3.15 中移除。請改用 locale.setlocale()、locale.getpreferredencoding(False) 和 locale.getlocale()。(Victor Stinner 於 gh-90817 中所貢獻。)
locale.resetlocale() 函式已棄用並將於 Python 3.13 中移除,請改用 locale.setlocale(locale.LC_ALL, "")。(由 Victor Stinner 於 gh-90817 中所貢獻。)
現在將對正規表示式中的數值群組參照 (numerical group references) 和群組名稱套用更嚴格的規則。現在只接受 ASCII 數字序列作為數值參照,並且 bytes 模式 (pattern) 的群組名稱和替換字串中只能包含 ASCII 字母、數字和底線。目前,會針對違反這些規則的語法發出棄用警告。(由 Serhiy Storchaka 在 gh-91760 中貢獻。)
在 re 模組中,re.template() 函式和相應的 re.TEMPLATE 和 re.T 旗標被棄用,因為它們沒被記錄於文件中並且缺乏明顯的目的。它們將在 Python 3.13 中被刪除。(由 Serhiy Storchaka 和 Miro Hrončok 在 gh-92728 中貢獻。)
turtle.settiltangle() 自 Python 3.1 以來已被棄用;它現在會發出棄用警告,並將在 Python 3.13 中刪除。請改用 turtle.tiltangle()(它之前被錯誤地標記為已棄用,其文件字串現在已更正)。(由 Hugo van Kemenade 在 bpo-45837 中貢獻。)
僅用於支援 Python 2 和 Python 3 程式碼間相容性的 typing.Text 現已棄用。目前未計劃刪除它,但鼓勵用戶盡可能使用 str 代替。(由 Alex Waygood 在 gh-92332 中貢獻。)
用於建構 typing.TypedDict 型別的關鍵字引數語法現已棄用。將在 Python 3.13 中停止支援。(由 Jingchen Ye 在 gh-90224 中貢獻。)
webbrowser.MacOSX 已被棄用且將於 Python 3.13 中移除。它並沒有被測試過、沒紀錄於文件、也沒有被 webbrowser 本身使用。(由 Donghee Na 於 bpo-42255。)
回傳從 TestCase 和 IsolatedAsyncioTestCase 測試方法(預設的 None 值除外)給定值的行為現已棄用。
棄用以下並沒有正式紀錄於文件中的 unittest 函式,並預計於 Python 3.13 中移除:
unittest.findTestCases()
unittest.makeSuite()
unittest.getTestCaseNames()
改用 TestLoader 方法:
(由 Erlend E. Aasland 於 bpo-5846 中所貢獻。)
unittest.TestProgram.usageExit() 被標記為已棄用,即將在 3.13 中移除(由 Carlos Damázio 在 gh-67048 中貢獻。)
下列 API 已在先前的 Python 發布版本中棄用,並將於 Python 3.12 中移除。
待定的 C API 移除項目為獨立列出的。
asynchat 模組
asyncore 模組
imp 模組
typing.io 命名空間
typing.re 命名空間
cgi.log()
importlib.find_loader()
importlib.abc.Loader.module_repr()
importlib.abc.MetaPathFinder.find_module()
importlib.abc.PathEntryFinder.find_loader()
importlib.abc.PathEntryFinder.find_module()
importlib.machinery.BuiltinImporter.find_module()
importlib.machinery.BuiltinImporter.module_repr()
importlib.machinery.FileFinder.find_loader()
importlib.machinery.FileFinder.find_module()
importlib.machinery.FrozenImporter.find_module()
importlib.machinery.FrozenImporter.module_repr()
importlib.machinery.PathFinder.find_module()
importlib.machinery.WindowsRegistryFinder.find_module()
importlib.util.module_for_loader()
importlib.util.set_loader()
importlib.util.set_package()
pkgutil.ImpImporter
pkgutil.ImpLoader
pathlib.Path.link_to()
sqlite3.enable_shared_cache()
sqlite3.OptimizedUnicode()
PYTHONTHREADDEBUG 環境變數
unittest 中被棄用的別名:
已棄用的別名
方法名稱
棄用於
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
此部分列出 Python 3.11 中移除的 Python API。
被移除的 C API 被獨立列出。
刪除了 @asyncio.coroutine() decorator 使遺留的基於生成器的協程 (generator-based coroutine) 與 async / await 程式碼相容。該函式自 Python 3.8 起已被棄用,計劃於 Python 3.10 刪除。請改用 async def。(由 Illia Volochii 在 bpo-43216 中貢獻。)
移除除錯模式中用於包裝遺留基於產生器之協程物件的 asyncio.coroutines.CoroWrapper。(由 Illia Volochii 於 bpo-43216 中貢獻。)
因為有重大的安全性考量,Python 3.9 中停用的 asyncio.loop.create_datagram_endpoint() 之 reuse_address 參數目前已經移除。這是因為 UDP socket 選項 SO_REUSEADDR 的行為所致。(由 Hugo van Kemenade 於 bpo-45129 中貢獻。)
移除 Python 3.9 中棄用的 binhex 模組,與其相關且相似的 binascii 函式也一併被移除:
binascii.a2b_hqx()
binascii.b2a_hqx()
binascii.rlecode_hqx()
binascii.rldecode_hqx()
binascii.crc_hqx() 維持可用。
(由 Victor Stinner 於 bpo-45085 中所貢獻。)
移除 Python 3.9 中棄用的 distutils bdist_msi 命令。請改用 bdist_wheel(wheel 套件)。(由 Hugo van Kemenade 於 bpo-45124 中貢獻。)
將 xml.dom.pulldom.DOMEventStream、wsgiref.util.FileWrapper 和 fileinput.FileInput 自 Python 3.9 中棄用的 __getitem__() 方法移除。(由 Hugo van Kemenade 在 bpo-45132 中貢獻。)
刪除了已棄用的 gettext 函式 lgettext()、ldgettext()、lngettext() 和 ldngettext(),也刪除了 bind_textdomain_codeset() 函式、NullTranslations.output_charset() 和 NullTranslations.set_output_charset() 方法,以及 translation() 和 install() 的 codeset 參數,因為它們僅被用於 l*gettext() 函式。(由 Donghee Na 和 Serhiy Storchaka 在 bpo-44235 中貢獻。)
於 inspect 模組中移除:
Python 3.0 中棄用的 getargspec();改用 inspect.signature() 或 inspect.getfullargspec()。
Python 3.5 中棄用的 formatargspec() 函式;請直接用 inspect.signature() 函式或 inspect.Signature 物件。
Python 3.5 中停用且沒有被紀錄於文件上的 Signature.from_builtin() 和 Signature.from_function() 方法;改用 Signature.from_callable() 方法。
(由 Hugo van Kemenade 於 bpo-45320 中所貢獻。)
自 pathlib.PurePath 中移除 __class_getitem__() 方法,因為它是前一版本中誤加且沒被使用。(由 Nikita Sobolev 於 bpo-46483 中所貢獻。)
移除 smtpd 模組中的 MailmanProxy 類別,因為它無法獨立於外部套件 mailman 使用。(由 Donghee Na 於 bpo-35800 貢獻。)
移除 _tkinter.TkappType 已被棄用的 split() 方法。(由 Erlend E. Aasland 於 bpo-38371 貢獻。)
從 unittest 中刪除了命名空間套件支援。它在 Python 3.4 中引入,但自 Python 3.7 以來已無法運作。(由 Inada Naoki 在 bpo-23882 中貢獻。)
將未被記錄於文件中的私有方法 float.__set_format__() 移除,它過去是 Python 3.7 中的 float.__setformat__()。它的文件字串 (docstring) 說到:「你大概不會想要使用這個函式,它只為了讓 Python 測試系列套件 (suite) 使用而存在。」(由 Victor Stinner 於 bpo-46852 中貢獻。)
移除 --experimental-isolated-subinterpreters 配置旗標(與對應的 EXPERIMENTAL_ISOLATED_SUBINTERPRETERS 巨集)。
Pynche --- Python 風格的自然色彩與色調編輯器 --- 已被移出 Tools/scripts,獨立開發於 Python 原始碼之外。
本部分列出了之前描述的 Python API 中可能需要你去更改 Python 程式碼的變更和其他錯誤修復。
C API 的移植被獨立列出。
open()、io.open()、codecs.open() 和 fileinput.FileInput 不再接受 'U'("universal newline",通用換行符)文件模式。在 Python 3 中,每當以文本模式 (text mode) 打開檔案時,預設情況下會使用「通用換行符」模式,並且自 Python 3.3 以來就不推薦使用 'U' 旗標。這些函式的 newline 參數控制了通用換行符的作用方式。(由 Victor Stinner 在 bpo-37330 中貢獻。)
ast.AST 節點位置現在會在提供給 compile() 和其他相關函式時被驗證。如果檢測到無效位置,則會引發 ValueError。(由 Pablo Galindo 在 gh-93351 中貢獻)
在 Python 3.8 中棄用後,禁止將非 concurrent.futures.ThreadPoolExecutor 執行器傳遞給 asyncio.loop.set_default_executor()。(由 Illia Volochii 在 bpo-43234 中貢獻。)
calendar:calendar.LocaleTextCalendar 和 calendar.LocaleHTMLCalendar 類別如果沒有指定語言環境,現在會使用 locale.getlocale() 而非 locale.getdefaultlocale()。(由 Victor Stinner 在 bpo-46659 中貢獻。)
pdb 模組現在會讀取 'UTF-8' 編碼的 .pdbrc 配置檔案。(Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి) 於 bpo-41137 貢獻。)
random.sample() 的 population 參數必須是一個序列,不再支援 set 到 list 的自動轉換。此外,如果抽樣大小大於總體大小,則會引發 ValueError。(由 Raymond Hettinger 在 bpo-40465 中貢獻。)
刪除了 random.shuffle() 的 random 可選參數。它以前是用於隨機排列 (shuffle) 的任意隨機函式;現在都會使用 random.random()(這是它以前的預設值)。
在 re Regular expression syntax 中,全域行內旗標(例如 (?i))現在只能在正規表示式的開頭使用。自 Python 3.6 以來,在其他地方使用它們已被棄用。(由 Serhiy Storchaka 在 bpo-47066 中貢獻。)
在 re 模組中修復了幾個長期存在的錯誤,在極少數情況下,這些錯誤可能會導致捕獲群組 (capture group) 得到錯誤的結果。因此,這可能會在這些情況下更改捕獲的輸出。(Ma Lin 在 bpo-35859 中貢獻。)
CPython 現在有 PEP 11 Tier 3 支援 以用於交叉編譯至 WebAssembly 平台 Emscripten(wasm32-unknown-emscripten,即瀏覽器中的 Python)和 WebAssembly 系統介面 (WASI) (wasm32-unknown-wasi)。這個靈感來自過往的貢獻,例如 Pyodide。這些平台提供了有限的 POSIX API 子集;Python 標準函式庫功能和與網路、行程、執行緒、訊號、mmap、用戶/群組相關的模組不開放使用或無法正常使用。(Emscripten 由 Christian Heimes 和 Ethan Smith 在 gh-84461 貢獻,WASI 由 Christian Heimes 在 gh-90473 貢獻;平台在 gh-95085 中推廣)
建置 CPython 現在必須要有:
Py_NO_NAN 巨集已被移除。因為 CPython 現在需要 IEEE 754 浮點數,NaN 數值皆為可得的。(由 Victor Stinner 在 bpo-46656 中貢獻。)
tkinter 套件現在必須要有 Tcl/Tk 8.5.12 或更新的版本。(由 Serhiy Storchaka 於 bpo-46996 中所貢獻。)
大多數 stdlib 擴充模組的依賴套件、編譯器旗標 (compiler flag) 和鏈接器旗標 (linker flags) 現在可以透過 configure 檢測出來。(當可用時)pkg-config 會檢測出 libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt、Tcl/Tk 和 uuid 旗標。tkinter 現在需要一個 pkg-config 命令來檢測 Tcl/Tk 標頭檔和函式庫的開發設定。(由 Christian Heimes 和 Erlend Egeberg Aasland 在 bpo-45847、bpo-45747 和 bpo-45763 中貢獻。)
libpython 不再鏈接到 libcrypt。(由 Mike Gilbert 在 bpo-45433 中貢獻。)
CPython 現在可以透過將 thin 傳遞給 --with-lto(也就是 --with-lto=thin)來以 ThinLTO 選項建置。(由 Donghee Na 與 Brett Holman 於 bpo-44340 中所貢獻。)
Freelists for object structs can now be disabled. A new configure
option --without-freelists can be used to disable all freelists
except empty tuple singleton.
(Contributed by Christian Heimes in bpo-45522.)
Modules/Setup 和 Modules/makesetup 已得到改進和綁定。現在可以透過 makesetup 建置擴充模組。除了一些測試模組外,所有模組都可以靜態鏈接到主要的二進制文件或函式庫中。(由 Brett Cannon 和 Christian Heimes 在 bpo-45548、bpo-45570、bpo-45571 和 bpo-43974 中貢獻。)
備註
使用環境變數 TCLTK_CFLAGS 和 TCLTK_LIBS 以手動指定 Tcl/Tk 標頭檔和函式庫的位置。configure 選項 —with-tcltk-includes 和 —with-tcltk-libs 已被刪除。
RHEL 7 和 CentOS 7 上的開發套件並無提供 tcl.pc 和 tk.pc;要使用 TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"。目錄 Misc/rhel7 包含 .pc 檔案與如何使用 RHEL 7 和 CentOS 7 的 Tcl/Tk 與 OpenSSL 建置 Python 的指示。
CPython 現在預設使用 30-bit 數字來實作 Python int。以前,在 SIZEOF_VOID_P >= 8 的平台上預設使用 30-bit 數字,否則使用 15-bit 數字,但仍能透過配置腳本的 --enable-big-digits 選項或(於 Windows)PC/pyconfig.h 中的 PYLONG_BITS_IN_DIGIT 變數來明確請求使用 15-bit 數字,但此選項可能會在將來的某個時候被刪除。(由 Mark Dickinson 在 bpo-45569 中貢獻。)
新增 PyType_GetName() 函式來取得型別的短名。(由 Hai Shi 於 bpo-42035 中所貢獻。)
新增 PyType_GetQualName() 函式來取得型別的合格名稱 (qualified name)。(由 Hai Shi 於 bpo-42035 中所貢獻。)
在受限 C API (limited C API) 中新增 PyThreadState_EnterTracing() 和 PyThreadState_LeaveTracing() 函式來中止和繼續追蹤 (tracing) 和性能分析 (profiling)。(由 Victor Stinner 於 bpo-43760 中貢獻。)
添加了 Py_Version 常數,其值與 PY_VERSION_HEX 相同。(由 Gabriele N. Tornetta 在 bpo-43931 中貢獻。)
Py_buffer 與 API 目前是受限 API 與穩定 ABI 中的一部分:
bf_getbuffer 與 bf_releasebuffer 型別插槽 (type slot)
(由 Christian Heimes 於 bpo-45459 中所貢獻。)
新增 PyType_GetModuleByDef() 函式,它將被用於取得定義一個方法的模組,以免這項資訊無法直接被取得(透過 PyCMethod)。(由 Petr Viktorin 於 bpo-46613 中所貢獻。)
新增函式以打包 (pack) 和取出 (unpack) C double(序列化和反序列化):PyFloat_Pack2()、PyFloat_Pack4()、PyFloat_Pack8()、PyFloat_Unpack2() , PyFloat_Unpack4() 和 PyFloat_Unpack8()。(由 Victor Stinner 在 bpo-46906 中貢獻。)
新增取得幀物件屬性的函式:PyFrame_GetBuiltins()、PyFrame_GetGenerator()、PyFrame_GetGlobals()、PyFrame_GetLasti()。
添加了兩個新函式來獲得和設置仍在作用的例外實例:PyErr_GetHandledException() 和 PyErr_SetHandledException()。這些是 PyErr_SetExcInfo() 和 PyErr_GetExcInfo() 的替代品,它們與例外的遺留三元組表示法一起作用。(由 Irit Katriel 在 bpo-46343 中貢獻。)
新增 PyConfig.safe_path 成員。(由 Victor Stinner 於 gh-57684 中所貢獻。)
一些巨集已轉換為行內靜態函式以避免巨集陷阱 (macro pitfalls)。這種變化對用戶來說應該是透明的,因為替換函式會將它們的引數轉換為預期的型別,以避免由於靜態型別檢查而產生的編譯器警告。但是,當受限 C API 設置為 >=3.11 時,這些轉換不會完成,使用者需要將引數轉換為他們期望的型別。有關更多詳細資訊,請參閱 PEP 670。(由 Victor Stinner 和 Erlend E. Aasland 在 gh-89653 中貢獻。)
PyErr_SetExcInfo() 不再使用 type 和 traceback 引數,直譯器現在從例外實例(value 引數)中獲得這些值。該函式仍會偷用這三個引數的參照。(由 Irit Katriel 在 bpo-45711 中貢獻。)
PyErr_GetExcInfo() 現在從例外實例的結果(value 欄位)中導出 type 和 traceback 欄位。(由 Irit Katriel 在 bpo-45711 中貢獻。)
_frozen 有一個新的 is_package 欄位來表示凍結模組是否為一個套件。以前 size 欄位中的負值是指標,現在只有非負值可用於 size。(由 Kumar Aditya 在 bpo-46608 中貢獻。)
_PyFrameEvalFunction() 現在將 _PyInterpreterFrame* 作為其第二個參數,而不是 PyFrameObject*。有關如何使用此函式指標型別的更多詳細資訊,請參閱 PEP 523。
PyCode_New() 和 PyCode_NewWithPosOnlyArgs() 現在採用額外的 exception_table 引數。如果可能的話應該避免使用這些函式。要取得自訂程式碼物件,使用編譯器建立一個程式碼物件,然後使用 replace 方法來得到修改後的版本。
PyCodeObject 不再會有 co_code、co_varnames、co_cellvars 和 co_freevars 欄位。分別被改為透過 C API 的 PyCode_GetCode()、PyCode_GetVarnames()、PyCode_GetCellvars() 和 PyCode_GetFreevars() 來存取。(由 Brandt Bucher 在 bpo-46841、Ken Jin 在 gh-92154 與 gh-94936 中貢獻。)
舊的回收筒巨集 (trashcan macro) (Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END) 現在已經被棄用,它們應被新的巨集 Py_TRASHCAN_BEGIN 和 Py_TRASHCAN_END 所取代。
一個用到老舊巨集的 tp_dealloc 函式,像是:
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_SAFE_BEGIN(p); ... Py_TRASHCAN_SAFE_END(p) }
應該要搬遷到新的巨集,如下所示:
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_BEGIN(p, mytype_dealloc) ... Py_TRASHCAN_END }
請注意 Py_TRASHCAN_BEGIN 有第二個引數,它應該是它所在的釋放函式 (deallocation function)。
為支援舊版 Python 在同一份程式碼中,你可以定義以下巨集並在程式碼中使用它們(要歸功於 mypy 程式碼,這些是從那邊複製過來的):
#if PY_VERSION_HEX >= 0x03080000 # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_END #else # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op) #endif
如果一個型別是以 Py_TPFLAGS_HAVE_GC 旗標來定義,但卻沒有遍歷函式 (traverse function) (PyTypeObject.tp_traverse),那 PyType_Ready() 函式現在會引發一個錯誤。(由 Victor Stinner 於 bpo-44263 中貢獻。)
帶有 Py_TPFLAGS_IMMUTABLETYPE 旗標的堆積型別現在可以繼承 PEP 590 向量呼叫協定 (vectorcall protocol)。以前這僅適用於 static types。(由 Erlend E. Aasland 在 bpo-43908 中貢獻)。
由於 Py_TYPE() 更改為行內靜態函式 (inline static function),因此 Py_TYPE(obj) = new_type 必須替換為 Py_SET_TYPE(obj, new_type):參見 Py_SET_TYPE() 函式(自 Python 3.9 起可用)。為了向後相容,可以使用這個巨集:
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type) #endif
(由 Victor Stinner 於 bpo-39573 中所貢獻。)
由於 Py_SIZE() 更改為行內靜態函式,因此 Py_SIZE(obj) = new_size 必須替換為 Py_SET_SIZE(obj, new_size):參見 Py_SET_SIZE() 函式(自 Python 3.9 起可用)。為了向後相容,可以使用這個巨集:
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; } #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) #endif
(由 Victor Stinner 於 bpo-39573 中所貢獻。)
當 Py_LIMITED_API 巨集被設定為 0x030b0000(Python 3.11)或以上,<Python.h> 不再會包含標頭檔 <stdlib.h>、<stdio.h>、<errno.h> 和 <string.h>。C 擴充程式應該要清楚的在 #include <Python.h> 之後引入標頭檔案。(由 Victor Stinner 於 bpo-45434 中貢獻。)
非受限 API (non-limited API) 檔案 cellobject.h、classobject.h、code.h、context.h、funcobject.h、genobject. h 和 longintrepr.h 已移至 Include/cpython 目錄。此外,eval.h 標頭檔已被刪除。不能直接引入這些文件,因為它們已被包含在 Python.h 中:引入檔案。如果它們已被直接引入,請考慮改為引入 Python.h。 (由 Victor Stinner 在 bpo-35134 中貢獻。)
PyUnicode_CHECK_INTERNED() 巨集已從受限 C API 中移出,它從來沒辦法被使用,因為它使用了受限 C API 不提供的內部結構。(由 Victor Stinner 於 bpo-46007 中所貢獻。)
以下用於幀 (frame) 的函式與型別現在可直接透過 #include <Python.h> 來使用,不必再加上 #include <frameobject.h>:
(由 Victor Stinner 於 gh-93937 中所貢獻。)
PyFrameObject 結構成員已經從公開的 C API 中移除。
雖然文件指出 PyFrameObject 欄位隨時可能發生變化,但它們已經穩定了很長時間,並被用於幾個流行的擴充套件中。
Python 3.11 中,幀的結構被重新編制來為性能做最佳化,有些作為舊版實作細節的欄位被整個移除。
PyFrameObject 欄位:
f_back:使用 PyFrame_GetBack()。
f_blockstack:已移除。
f_builtins:使用 PyFrame_GetBuiltins()。
f_code:使用 PyFrame_GetCode()。
f_gen:使用 PyFrame_GetGenerator()。
f_globals:使用 PyFrame_GetGlobals()。
f_iblock:已移除。
f_lasti:使用 PyFrame_GetLasti()。程式碼中 f_lasti 有與 PyCode_Addr2Line() 同時使用的部分應該改用 PyFrame_GetLineNumber();它可能會更快。
f_lineno:使用 PyFrame_GetLineNumber()
f_locals:使用 PyFrame_GetLocals()。
f_stackdepth:已移除。
f_state:無公開 API(重新命名為 f_frame.f_state)。
f_trace:無公開 API。
f_trace_lines:使用 PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")。
f_trace_opcodes:使用 PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")。
f_localsplus:無公開 API(重新命名為 f_frame.localsplus)。
f_valuestack:已移除。
Python 幀物件的建立現為惰性的 (lazily),一個副作用是 f_back 成員不能被直接存取,因為其職的計算也是惰性的,要改呼叫 PyFrame_GetBack()。
直接存取 f_locals 的除錯器必須改為呼叫 PyFrame_GetLocals()。他們不再需要呼叫 PyFrame_FastToLocalsWithError() 或 PyFrame_LocalsToFast(),事實上他們不應該呼叫這些函式。框架的必要更新現在由虛擬機管理。
PyFrame_GetCode() 在 Python 3.8 以前的程式定義:
#if PY_VERSION_HEX < 0x030900B1 static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) { Py_INCREF(frame->f_code); return frame->f_code; } #endif
PyFrame_GetBack() 在 Python 3.8 以前的程式定義:
#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) { Py_XINCREF(frame->f_back); return frame->f_back; } #endif
或是使用 pythoncap_compat 計畫來在舊版 Python 函式中取得這兩個函式。
PyThreadState 結構成員的改動:
frame:已移除,改用 PyThreadState_GetFrame()(bpo-40429 於 Python 3.9 新增的函式)。警告:會回傳 strong reference 的函式必須呼叫 Py_XDECREF()。
tracing:已變更,改用 PyThreadState_EnterTracing() 和 PyThreadState_LeaveTracing()(bpo-43760 於 Python 3.11 中新增的函式)。
recursion_depth:已移除,請改用 (tstate->recursion_limit - tstate->recursion_remaining)。
stackcheck_counter:已移除。
PyThreadState_GetFrame() 在 Python 3.8 以前的程式定義:
#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { Py_XINCREF(tstate->frame); return tstate->frame; } #endif
PyThreadState_EnterTracing() 與 PyThreadState_LeaveTracing() 在 Python 3.10 以前的程式定義:
#if PY_VERSION_HEX < 0x030B00A2 static inline void PyThreadState_EnterTracing(PyThreadState *tstate) { tstate->tracing++; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = 0; #else tstate->use_tracing = 0; #endif } static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) { int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); tstate->tracing--; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = use_tracing; #else tstate->use_tracing = use_tracing; #endif } #endif
或是使用 pythoncap-compat 專案來在舊版 Python 函式中取得它們。
鼓勵發布者們使用最佳化過的 Blake2 函式庫 libb2 來建置 Python。
初始化中若是要用 PyConfig.module_search_paths 來初始化 sys.path,則現在 PyConfig.module_search_paths_set 必須被設為 1。否則,初始化會重新計算路徑並取代所有被加到 module_search_paths 的值。
PyConfig_Read() 不再計算初始搜尋路徑,並且不會將任何值填充到 PyConfig.module_search_paths 中。若要計算預設路徑然後修改它們,完成初始化並使用 PySys_GetObject() 以取得 sys.path 作為 Python 列表物件並直接修改它。
棄用以下用來配置 Python 初始化的函式:
PySys_AddWarnOptionUnicode()
PySys_AddWarnOption()
PySys_AddXOption()
PySys_HasWarnOptions()
PySys_SetArgvEx()
PySys_SetArgv()
PySys_SetPath()
Py_SetPath()
Py_SetProgramName()
Py_SetPythonHome()
Py_SetStandardStreamEncoding()
_Py_SetProgramFullPath()
請改用 Python 初始化配置中新的 PyConfig API。(由 Victor Stinner 於 gh-88279 中所貢獻。)
棄用 PyBytesObject 中的 ob_shash 成員。請改用 PyObject_Hash()。(由 Inada Naoki 於 bpo-46864 中所貢獻。)
以下 C API 已於先前 Python 發布版本中棄用,並將於 Python 3.12 中移除。
PyUnicode_AS_DATA()
PyUnicode_AS_UNICODE()
PyUnicode_AsUnicodeAndSize()
PyUnicode_AsUnicode()
PyUnicode_FromUnicode()
PyUnicode_GET_DATA_SIZE()
PyUnicode_GET_SIZE()
PyUnicode_GetSize()
PyUnicode_IS_COMPACT()
PyUnicode_IS_READY()
PyUnicode_WSTR_LENGTH()
_PyUnicode_AsUnicode()
PyUnicode_WCHAR_KIND
PyUnicode_InternImmortal()
PyFrame_BlockSetup() and PyFrame_BlockPop() have been
removed.
(Contributed by Mark Shannon in bpo-40222.)
移除以下使用到 errno 變數的數學巨集:
Py_ADJUST_ERANGE1()
Py_ADJUST_ERANGE2()
Py_OVERFLOWED()
Py_SET_ERANGE_IF_OVERFLOW()
Py_SET_ERRNO_ON_MATH_ERROR()
(由 Victor Stinner 於 bpo-45412 中所貢獻。)
移除在 Python 3.3 中棄用的 Py_UNICODE_COPY() 和 Py_UNICODE_FILL()。請改用 PyUnicode_CopyCharacters() 或 memcpy()(wchar_t* 字串)和 PyUnicode_Fill() 函式。(由 Victor Stinner 於 bpo-41123 中所貢獻。)
移除 pystrhex.h 標頭檔案。它只有包含私有函式。C 的擴充應該只要引入主要的 <Python.h> 標頭檔案。(由 Victor Stinner 於 bpo-45434 中所貢獻。)
移除 Py_FORCE_DOUBLE() 巨集。它先前被用於 Py_IS_INFINITY() 巨集。(由 Victor Stinner 於 bpo-45440 中所貢獻。)
當 Py_LIMITED_API 有被定義時,以下項目將無法被取得:
Py_MARSHAL_VERSION 巨集
These are not part of the limited API.
(由 Victor Stinner 於 bpo-45474 中所貢獻。)
Exclude PyWeakref_GET_OBJECT() from the limited C API. It never
worked since the PyWeakReference structure is opaque in the
limited C API.
(Contributed by Victor Stinner in bpo-35134.)
移除 PyHeapType_GET_MEMBERS() 巨集,它是不小心才被放到公開的 C API 中,應該只能被 Python 內部所使用。請改用 PyTypeObject.tp_members。(由 Victor Stinner 於 bpo-40170 中所貢獻。)
移除 HAVE_PY_SET_53BIT_PRECISION 巨集(移動至內部 C API)。(由 Victor Stinner 於 bpo-45412 中所貢獻。)
移除 Py_UNICODE 編碼器 API,它們自從 Python 3.3 就被棄用,非常少用且和推薦的替代方案已無太大關聯。
被移除的函式為:
PyUnicode_Encode()
PyUnicode_EncodeASCII()
PyUnicode_EncodeLatin1()
PyUnicode_EncodeUTF7()
PyUnicode_EncodeUTF8()
PyUnicode_EncodeUTF16()
PyUnicode_EncodeUTF32()
PyUnicode_EncodeUnicodeEscape()
PyUnicode_EncodeRawUnicodeEscape()
PyUnicode_EncodeCharmap()
PyUnicode_TranslateCharmap()
PyUnicode_EncodeDecimal()
PyUnicode_TransformDecimalToASCII()
The extraction methods in tarfile, and shutil.unpack_archive(),
have a new a filter argument that allows limiting tar features than may be
surprising or dangerous, such as creating files outside the destination
directory.
See 解壓縮篩選器 for details.
In Python 3.12, use without the filter argument will show a
DeprecationWarning.
In Python 3.14, the default will switch to 'data'.
(Contributed by Petr Viktorin in PEP 706.)
Windows builds and macOS installers from python.org now use OpenSSL 3.0.