跳到主要內容
maxstudioNews
產品Simon Willison約 6 分鐘

Python 3.15 釋出:告別 3.10,擁抱 3.11 新功能

Python 3.15 正式發布,帶來了多項新功能,其中最受矚目的包括 PEP 810 的明確延遲載入(Explicit lazy imports)和 PEP 798 的推導式解包語法。此外,新的取樣分析器 Tachyon 也整合進標準函式庫,提供低開銷的效能洞察。隨著 3.15 的推出,Python 3.10 終止支援,開發者現在可以開始利用 3.11 版本引入的各種改進,例如 asyncio 和 SQLite 支援的強化。

Python 3.15 釋出:告別 3.10,擁抱 3.11 新功能
圖片來源:Simon Willison

Python 3.15 已經正式發布!今年由 3.14 和 3.15 的發布經理 Hugo van Kemenade 策劃了這份《Python 3.15 新功能指南》。身為一個開發支援所有 Python 版本的開源軟體的人,我終於可以告別 Python 3.10,並開始擁抱 Python 3.11 的新功能了。

首先,來看看 Python 3.15 的一些亮點。

我對 PEP 810 提出的「明確延遲載入」(Explicit lazy imports)感到最興奮。這項功能讓你可以像這樣載入模組:

lazy import json

lazy from pathlib import Path

這些模組會在程式碼中首次使用到這些符號時才被載入。我的 LLM CLI 工具實作了外掛功能,我過去必須在外掛作者文件中建議手動延遲載入,因為如果外掛使用了像 sentence_transformers 這樣的大型依賴項,每次呼叫 llm 指令都可能增加數秒的啟動時間。延遲載入直接解決了這個啟動成本問題。

新的推導式解包語法 [*sublist for sublist in lists] 也非常實用。以下是從文件中擷取的範例:

lists = [[1, 2], [3, 4], [5]]

[*L for L in lists]

[1, 2, 3, 4, 5]

等同於 [x for L in lists for x in L]

sets = [{1, 2}, {2, 3}, {3, 4}]

{*s for s in sets}

{1, 2, 3, 4}

等同於 {x for s in sets for x in s}

dicts = [{'a': 1}, {'b': 2}, {'a': 3}]

{**d for d in dicts}

{'a': 3, 'b': 2}

等同於 {k: v for d in dicts for k,v in d.items()}

PEP 798: Unpacking in Comprehensions(由 Adam Hartz 和 Erik Demaine 提出)將此功能作為 PEP 448 解包語法的擴展,後者已於 2015 年隨 Python 3.5 推出。

Python 現有的追蹤分析器已從 cProfile 更名為 profiling.tracing,並新增了一個令人興奮的取樣分析器,名為 Tachyon,也就是 profiling.sampling。

取樣分析器透過定期擷取執行中程序的堆疊追蹤來運作,然後利用這些資訊計算哪些函式花費了最多的時間。它們的開銷非常低,可以對執行中的系統提供深入的洞察,而無需事先對這些系統進行儀器化。

我之前曾使用 py-spy 等工具來實現此功能,現在這項能力已內建於標準函式庫中。如果你有一個現有的 Python 3.15 程序的 PID,你可以執行以下指令開始收集樣本(我在 macOS 上必須使用 sudo):

sudo uv run --python 3.15 python -m profiling.sampling attach 1234

與主程式互動一會兒,然後按下 Ctrl+C 停止收集,即可看到一份報告,其外觀大致如下圖所示。它還可以產生像火焰圖和熱力圖,甚至可以輸出成能在 Firefox 分析器 UI 中檢視的格式。

Miguel Grinberg 前幾天針對 3.15.0rc3 版本調查了「Python 3.15 有多快?」,發現其效能與 3.14 大致相同,但實驗性的 JIT 除外。JIT 在 Fibonacci 測試中比標準 3.15 解譯器提供了 1.2 倍的提升,這是 Miguel 首次觀察到 JIT 帶來有意義的效能增長。

Miguel 去年對 3.14 的探索發現,與 Python 3.13 相比,許多類別的效能都有顯著提升。

我使用以下指令序列讓 uv 在我的 Mac 上使用 Python 3.15。首先,我必須升級 uv 本身,以確保它知道新版本:

uv self update

然後我安裝了穩定的 3.15 版本:

uv python install 3.15

並告知 uv 我希望它成為所有 uv run 指令的預設版本,除非專案本身鎖定不同的版本:

uv python pin --global 3.15

現在,以下指令會回報 3.15 為版本:

uv run python --version

我已經使用 uv tool install 安裝了一堆工具。我重新安裝它們以使用 Python 3.15,如下所示:

uv tool upgrade datasette --python 3.15

然後我可以像這樣確認版本:

datasette --get /-/versions.json | jq

隨著 3.15 的發布,Python 3.10(於 2021 年發布)已正式停止支援。我的主要開源專案政策是讓它們在所有受支援的 Python 版本中都能運作,因此我現在可以放棄 3.10,並開始使用 3.11 中引入的功能。

這是《Python 3.11 新功能文件》。我終於可以依賴 tomllib 的可用性了!Datasette 大量使用 asyncio,而 3.11 新增了 TaskGroup 和 timeout(),以及其他幾個新功能。

datetime.UTC 是 3.11 中 datetime.timezone.utc 的新別名。Python 的 SQLite 支援在 3.11 中獲得了一些重大升級,包括:

setlimit() 和 getlimit() 暴露了一種從 Python 設定 SQLite 執行時限制的機制。

create_window_function() 讓我們可以在 Python 中建立自訂的視窗函式,作為一個具有 step()、value()、inverse() 和 finalize() 方法的類別。

blobopen() 提供了一種高效的機制,用於對儲存在 SQLite 資料列中的大型 BLOB 二進位值進行部分讀取和寫入。你現在可以呼叫 set_authorizer(None) 來移除 SQLite 授權器,Datasette 過去為此有一個解決方法!

此外,Python 的型別系統也獲得了一系列改進。我計畫在接下來的幾週內將 Python 3.11 的改進應用到我的一些專案中。這是我的第一個 Datasette PR,用於移除 set_authorizer(None) 的解決方法。

我也更新了我的 click-app、datasette-plugin、python-lib 和 llm-plugin cookiecutter 模板,以針對 Python 3.11 到 Python 3.15 進行測試。

Share

覺得值得一看?分享給朋友。

以上為 AI 自動翻譯導讀。原文版權歸 Simon Willison 所有, 建議透過「閱讀原文」前往原始網站,以取得最完整資訊並支持原作者。

Newsletter

不用每天追,AI 重點每週寄給你

43 個來源、每 2 小時更新,太多看不完。電子報每週挑最值得看的幾則,附上 Max 的看法。

每週一封。Email 只用來寄電子報,每封信都能一鍵退訂。