Python 3.15 已于 2026 年 10 月 9 日正式发布。本次更新在语言层面和性能优化上都带来了多项令人振奋的改进。其中,显式懒加载(lazy imports)解决了大型应用启动慢的瓶颈,frozendict 的加入填补了不可变字典的空白,推导式解包让代码更加简洁,而为自由线程(free-threaded)构建提供的稳定 ABI 则进一步拥抱了多线程时代。笔者将为你深度解读本次发布中最核心的几项新特性。
PEP 810:显式懒加载(Explicit lazy imports)
大型 Python 应用经常面临启动缓慢的问题,很大一部分原因是由于模块导入导致的连锁反应。过去,开发者通常将导入语句放入函数内部,或者使用 importlib 按需加载。Python 3.15 提供了一个更优雅的解决方案:通过 lazy 软关键字实现显式懒加载。
使用 lazy import 时,Python 不会立即加载模块,而是创建一个轻量级的代理对象,直到该模块中的名称首次被访问时才真正执行加载。
lazy import json
lazy from pathlib import Path
print("Starting up...") # json 和 pathlib 尚未完全导入
data = json.loads('{"key": "value"}') # 此时 json 才被完全导入
p = Path(".") # 此时 pathlib 才被完全导入
如果懒加载的模块不存在,异常将在首次访问时抛出。开发者还可以通过环境变量 PYTHON_LAZY_IMPORTS 或命令行参数 -X lazy_imports 来全局控制懒加载行为。
PEP 814:新增内置类型 frozendict
Python 3.15 引入了新的不可变内置类型 frozendict。它继承自 object,而不是 dict 的子类。只要它的键和值都是可哈希的(hashable),frozendict 本身就是可哈希的。frozendict 会保留插入顺序,但在进行比较时不会考虑顺序。
它的加入使得在需要不可变映射(如作为字典的键或集合的元素)时更加方便。
>>> a = frozendict(x=1, y=2)
>>> a
frozendict({'x': 1, 'y': 2})
>>> a['z'] = 3
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
a['z'] = 3
~^^^^^
TypeError: 'frozendict' object does not support item assignment
>>> b = frozendict(y=2, x=1)
>>> hash(a) == hash(b)
True
>>> a == b
True
PEP 798:推导式解包(Unpacking in comprehensions)
列表、集合、字典推导式以及生成器表达式现在支持使用 * 和 ** 进行解包。这是对 PEP 448 解包语法的自然延伸,使得将多个可迭代对象或字典合并为单一扁平结构变得十分简便,是嵌套推导式或 itertools.chain() 的直接替代方案。
>>> lists = [[1, 2], [3, 4], [5]]
>>> [*L for L in lists] # 等同于 [x for L in lists for x in L]
[1, 2, 3, 4, 5]
>>> sets = [{1, 2}, {2, 3}, {3, 4}]
>>> {*s for s in sets} # 等同于 {x for s in sets for x in s}
{1, 2, 3, 4}
>>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
>>> {**d for d in dicts} # 等同于 {k: v for d in dicts for k,v in d.items()}
{'a': 3, 'b': 2}
生成器表达式也同样适用:
>>> gen = (*L for L in lists) # 等同于 (x for L in lists for x in L)
>>> list(gen)
[1, 2, 3, 4, 5]
PEP 661:新增内置类型 sentinel
Python 3.15 在 builtins 模块中新增了 sentinel 类型,用于创建具有简洁表示的唯一哨兵值(sentinel values)。哨兵对象在复制时能保持身份的一致性,支持在类型表达式中使用 | 运算符,并且当它们可以通过模块和名称导入时,还支持被 pickle 序列化。
PEP 803:自由线程构建的稳定 ABI(abi3t)
针对自由线程(free-threaded)的 Python 构建,C 扩展现在可以使用新的自由线程稳定 ABI(被称为 abi3t)进行编译。这需要对源代码进行一些修改,例如切换到 PEP 697 中的 API,以及使用 PEP 793 引入的新导出钩子 PyModExport_* 等。
无法切换到 abi3t 的扩展应继续分别为现有的稳定 ABI(abi3)和特定于版本的自由线程 ABI(cp315t)进行构建。
升级建议与注意事项
| 建议维度 | 详细说明 |
|---|---|
| 谁应该升级 | 对启动速度有较高要求的大型应用开发者;需要处理大量复杂字典合并操作的开发者;积极适配自由线程 C 扩展的库维护者。 |
| 何时升级 | 可以在本地开发与测试环境中立即开始尝试 Python 3.15。生产环境建议等待相关依赖(尤其是使用 C 扩展的库)适配 abi3t 或 cp315t 后再进行迁移。 |
| 注意事项 | • cProfile 的相关追踪功能被整合进了新的 profiling 模块中(PEP 799)。• 旧的 profile 模块被弃用,并将在 Python 3.17 中移除。• .pth 文件中的 import 行被静默弃用,建议改用新的 .start 配置文件(PEP 829)。• PyGILState 系列 API 已被软弃用,未来将不再增加新的此类 API(PEP 788)。 |