Python 3.15 发布,开源项目可告别 3.10 并开始使用 3.11
Hello Python 3.15, goodbye 3.10, and now I can use 3.11
Python 3.15 已发布,Simon Willison 因此可让自己的开源项目停止支持已结束官方支持的 Python 3.10,并开始使用 3.11 的特性。
12th October 2026
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 的 显式惰性导入。它们让你可以这样导入模块:
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] # equivalent to [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} # equivalent to {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} # equivalent to {k: v for d in dicts for k,v in d.items()}
由 Adam Hartz 和 Erik Demaine 提出的 PEP 798:推导式中的解包 将此作为解包语法的扩展,该语法 来自 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 分析器界面中查看的格式。
3.15 并没有比 3.14 快多少
Miguel Grinberg 前几天针对 3.15.0rc3 版本调查了 Python 3.15 有多快?,发现性能大体与 3.14 相同,实验性 JIT 除外。JIT 相比标准 3.15 解释器带来了 1.2 倍提升(在斐波那契测试中),这是 Miguel 首次观察到有意义的 JIT 性能提升。
Miguel 去年 对 3.14 的探索 发现,相较于 Python 3.13,在更多类别上都有显著提升。
使用 uv 升级到 Python 3.15
我使用以下一系列命令,让 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 | jqPython 3.11 的亮点
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 authorizer。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 进行测试。
来源:Simon Willison · simonwillison.net