Python 3.15 来了!这里是必不可少的《Python 3.15 新特性》指南,今年由 3.14 和 3.15 的发布经理 Hugo van Kemenade 整理。作为一个构建可在所有受支持 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()}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 profiler UI 中查看的格式。
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 在我的 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 进行测试。
转载声明:本文为转载整理,原文版权归原作者及原站点所有。
原文来源:Simon Willison
原文作者:Simon Willison;如有侵权,请联系管理员删除。