Python 3.12 新特性盤點:從錯誤消息到性能優化
Python 3.12 引入了一系列顯著的特性和改進,進一步提升了開發者的體驗和語言的性能。該版本在錯誤消息方面做了重要改進,提供了更詳細且富有指導性的提示,幫助開發者更快定位問題。格式化字符串(f-strings)的功能也得到了增強,允許更強大的字符串格式化。
在性能優化方面,Python 3.12 繼續推進 faster-cpython 項目,通過加速和專門化字節碼執行,顯著提升了代碼的運行速度。該版本還改進了列表推導和其他推導操作的執行效率,使得數據處理更加高效。
此外,Python 3.12 支持 Linux perf Profiler,為性能分析提供了更多工具。每個子解釋器現在配備獨立的 GIL(全局解釋器鎖),提高了并發性能。新增了不可變對象和用于顯式繼承的覆蓋裝飾器,并引入了 itertools.batched() 方法以便將可迭代對象中的項目分組,以及改進了 Path.walk() 方法以列出文件和子目錄。這些改進進一步增強了 Python 作為開發語言的功能性和靈活性。
改進的錯誤消息
在 Python 3.10 中,許多錯誤消息,尤其是語法錯誤消息,變得更加詳細和準確。同樣,Python 3.11 在追蹤回溯信息中增加了更多內容,使得定位出錯代碼變得更加方便。
最新版本的 Python 3.12 繼續改善開發者體驗,提供了更好的錯誤消息。特別是一些常見的錯誤消息現在附帶了有用的建議。
圖片
當您在沒有先導入 math 的情況下使用它時,您會得到一個傳統的 NameError。此外,解析器會幫助提醒您在訪問 math 之前需要導入它。
關于提示導入模塊的提醒僅適用于標準庫模塊。對于這些錯誤消息,Python 3.12 不會跟蹤安裝的第三方包。
目前由于ipython有字節錯誤處理機制,提示導入包在ipython 里面沒有實現。
圖片
可以使用 from-import 語句從模塊中導入特定名稱。如果您不小心將關鍵字的順序顛倒了,現在會得到一個友好的提示,指導您使用正確的語法:
圖片
看看如果您從 math 模塊導入 py 而不是 pi 會發生什么:
圖片
更強大的 F-string
格式化字符串,簡稱 f-string,是在 PEP 498 和 Python 3.6 中引入的。通過 f-string,Python 增加了字符串格式化功能。您可以通過前導的 f 來識別 f-string,如以下示例:
圖片
關于F-String 在python 3.12 新特征,可以參考:《一文帶您了解F-string:解鎖Python3.12下F-string的新特性》
更快的 Python:更多專門化和內聯列表推導
當 Python 3.11 在 2022 年發布時,關于解釋器優化的討論非常熱烈,這些優化使得 Python 變得更快。這項工作是名為 faster-cpython 的持續努力的一部分,并在 Python 3.12 中繼續進行。
在 Python 腳本開始運行之前,代碼會被轉換成字節碼。字節碼是 Python 解釋器執行的代碼。Python 3.11 使用了一個專門的自適應解釋器,它可以在執行過程中改變和調整字節碼,以優化經常發生的操作。這包括兩個步驟:
- 加速:識別某些字節碼被多次執行,使其成為專門化的候選對象。
- 專門化:解釋器將一般的字節碼替換為專門化的字節碼。例如,將兩個浮點數相加的操作可以替換為一個專門化的加法操作。
在 Python 3.12 中,加速的過程比 Python 3.11 更快,解釋器現在可以專門化更多的新字節碼。要查看加速和專門化的實際效果,請定義以下函數:
圖片
每一行顯示有關一個字節碼指令的信息。五列分別是行號、字節地址、操作碼名稱、操作參數,以及參數的解釋(括號內)。
不需要理解這個字節碼列表的細節。一行 Python 代碼通常會編譯成多個字節碼指令,在這個例子中,return 0.3048 * feet 被翻譯成四條字節碼指令。
實際上,現在沒有單獨的加速步驟。原則上,所有字節碼指令都立即準備好進行專門化。在 Python 3.11 中,專門化在字節碼執行了相同類型八次后才開始。而python 3.12,這一過程在執行兩次后就會發生:
圖片
解釋器調整了原始BINARY_OP指令,將其替換為BINARY_OP_MULTIPLY_FLOAT,當兩個操作數都是float時,速度會更快。
解釋器優化調整某些字節碼,同時也不會損害 Python 的動態特性。仍然可以使用feet_to_meters()調整參數。使用相同數據類型的唯一好處是您的程序可能會運行得更快。
Python 支持列表推導、字典推導和集合推導,您可以使用它們來轉換可迭代對象。例如:
圖片
比如下面的列表推導式在以前python版本中,會編譯為嵌套的字節代碼,如下:
圖片
而在pythyon 3.12 版本中,推導式被編譯為內部字節代碼,也在就是內聯推導,大大加快的執行速度。如下圖:
圖片
此外Python 3.12 在多個方面進行了改進,包括對 Linux perf Profiler 的支持、每個子解釋器一個 GIL 的機制,以及引入了不可變對象。此外,新增了用于顯式繼承的覆蓋裝飾器。該版本還引入了 itertools.batched() 方法,以便將可迭代對象中的項目分組,并改進了 Path.walk() 方法。