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