Python 3.15 新特性
更新日期:2026 年 7 月 25 日
当前状态:Python 3.15.0 Beta 4
正式版计划发布日期:2026 年 10 月 1 日
Python 3.15 已于 Beta 1 阶段冻结新功能。本文内容基本确定,但个别实现细节仍可能在正式版发布前调整。
目录
一、语言与内置类型
1. 显式延迟导入(PEP 810)
Python 3.15 引入 lazy 软关键字,可以把模块的实际加载推迟到第一次使用时,从而缩短大型应用和命令行工具的启动时间。
lazy import json
lazy from pathlib import Path
print("程序已启动") # 此时尚未真正加载 json 和 pathlib
data = json.loads("{}") # 第一次使用时加载 json
path = Path(".") # 第一次使用时加载 pathlib
当延迟导入失败时,异常将在第一次使用对应名称时抛出,而不是在导入语句处立即抛出。回溯信息会同时指出访问位置和原始导入位置。
也可以通过命令行全局启用延迟导入:
python -X lazy_imports=all app.py
或使用环境变量:
PYTHON_LAZY_IMPORTS=all python app.py
运行时还提供以下接口:
import sys
sys.set_lazy_imports("all")
print(sys.get_lazy_imports())
使用限制
lazy 导入只能出现在模块作用域,不能用于:
- 函数或类定义内部;
try、except或finally块;- 星号导入;
__future__导入。
以下写法均不合法:
lazy from package import *
lazy from __future__ import annotations
lazy 是软关键字,因此仍然可以作为普通变量名使用。
2. 内置 frozendict(PEP 814)
Python 3.15 新增不可变映射类型 frozendict。它与 dict 类似,但创建后不能修改。
config = frozendict(
host="localhost",
port=8080,
)
print(config["host"])
config["port"] = 9000
# TypeError: 'frozendict' object does not support item assignment
如果所有键和值都可哈希,frozendict 本身也可哈希,因此可以作为字典键或集合元素:
cache = {
frozendict(x=1, y=2): "result",
}
frozendict 的主要特征:
- 创建后不可修改;
- 保留插入顺序;
- 相等性比较不考虑插入顺序;
- 键和值均可哈希时,自身也可哈希;
- 直接继承自
object,不是dict的子类。
a = frozendict(x=1, y=2)
b = frozendict(y=2, x=1)
assert a == b
assert hash(a) == hash(b)
如果程序需要同时接受 dict 和 frozendict,推荐使用抽象映射类型判断:
from collections.abc import Mapping
if isinstance(value, Mapping):
...
3. 内置 sentinel(PEP 661)
Python 3.15 新增内置 sentinel 类型,用于创建语义明确且身份唯一的哨兵值。
MISSING = sentinel("MISSING")
def get_value(value=MISSING):
if value is MISSING:
print("没有传入参数")
它可以代替过去常见但表达不够清晰的写法:
MISSING = object()
内置 sentinel 的优点包括:
repr()更清楚;- 复制后仍保持身份;
- 在满足条件时可以序列化;
- 支持在类型表达式中使用;
- 适合作为默认参数、缺失值和状态标记。
判断哨兵值时应使用 is:
if value is MISSING:
...
4. 推导式支持解包(PEP 798)
列表、集合和字典推导式以及生成器表达式现在支持 * 和 ** 解包。
扁平化列表
groups = [[1, 2], [3, 4], [5]]
result = [*group for group in groups]
# [1, 2, 3, 4, 5]
相当于:
result = [
value
for group in groups
for value in group
]
合并集合
sets = [{1, 2}, {2, 3}, {3, 4}]
result = {*items for items in sets}
# {1, 2, 3, 4}
合并字典
dicts = [
{"name": "Alice"},
{"age": 20},
{"name": "Bob"},
]
result = {**item for item in dicts}
# {'name': 'Bob', 'age': 20}
与普通字典解包一样,后面的同名键会覆盖前面的键。
生成器表达式
gen = (*group for group in groups)
print(list(gen))
# [1, 2, 3, 4, 5]
异步生成器表达式也支持这种语法。
5. 默认使用 UTF-8(PEP 686)
Python 3.15 默认使用 UTF-8 作为文本编码,不再依赖操作系统的区域设置。
with open("data.txt") as file:
text = file.read()
在 Python 3.15 中,上述代码默认相当于:
with open("data.txt", encoding="utf-8") as file:
text = file.read()
如果必须使用当前系统的区域编码,可以明确指定:
with open("data.txt", encoding="locale") as file:
text = file.read()
也可以暂时恢复旧行为:
python -X utf8=0 app.py
或设置:
PYTHONUTF8=0 python app.py
为了兼容旧版 Python 及清晰表达文件格式,跨版本项目仍建议明确填写编码:
open("data.txt", encoding="utf-8")
二、性能分析与可观测性
6. 统一的 profiling 包(PEP 799)
Python 内置性能分析工具被整理到新的 profiling 命名空间:
profiling.tracing:确定性函数调用分析,来源于cProfile;profiling.sampling:新的统计采样分析器 Tachyon。
cProfile 将继续作为兼容别名保留。旧的 profile 模块已被弃用,并计划在 Python 3.17 中删除。
7. Tachyon 高速采样分析器
profiling.sampling 提供新的统计采样分析器 Tachyon。它可以附加到正在运行的 Python 进程,不需要修改代码或重启目标程序。
python -m profiling.sampling attach <PID>
也可以直接启动并分析脚本:
python -m profiling.sampling run app.py
主要能力包括:
- 附加到正在运行的进程;
- 无需修改应用代码;
- 官方文档称采样频率最高可达约 1,000,000 Hz;
- 支持分析所有线程或只分析主线程;
- 可以感知
asyncio任务; - 支持墙钟时间、CPU 时间、GIL 持有时间和异常处理时间等模式;
- 支持火焰图、
pstats等输出格式; - 可抓取一次性线程或异步任务快照。
相较于记录每次函数调用的确定性分析器,统计采样通常具有更低的运行时开销,适合生产环境性能诊断。
8. 默认启用栈帧指针(PEP 831)
在支持的平台上,CPython 默认通过类似以下编译选项保留 frame pointer:
-fno-omit-frame-pointer
-mno-omit-leaf-frame-pointer
这会改善:
- 原生栈回溯;
- eBPF 性能观测;
- 系统级性能分析器;
- 调试器和崩溃分析工具;
- Python 与 C、C++、Rust 扩展之间的混合调用栈分析。
相关编译参数会通过 sysconfig 暴露。扩展模块和第三方构建系统应保留这些参数,否则原生调用链中任何一个未保留 frame pointer 的组件都可能破坏完整的栈展开。
三、解释器与性能
9. JIT 编译器升级
Python 3.15 的实验性 JIT 编译器获得了多项重要改进:
- 使用新的追踪前端;
- 支持更多字节码指令和控制流;
- 支持更多对象创建、重载操作和部分生成器场景;
- 加入基础寄存器分配;
- 增强常量传播等优化;
- 改进机器码生成;
- 支持 GDB 和原生栈回溯;
- 增加 Windows 支持;
- 构建阶段使用 LLVM 21。
开发文档中的初步基准结果显示:
- 在 x86-64 Linux 上,相对优化后的普通解释器,几何平均性能提高约 8%~9%;
- 在 ARM64 macOS 上,相对 tail-calling 解释器,性能提高约 12%~13%。
注意:这些并非最终性能数据。不同程序可能出现明显加速、没有变化甚至变慢,不能理解为所有 Python 程序都会获得固定比例的提升。
LLVM 仅在构建启用 JIT 的 CPython 时需要,运行预编译 Python 的最终用户不需要安装 LLVM。
10. Windows 64 位版本采用尾调用解释器
Python 3.15 官方 Windows 64 位二进制版本采用 tail-calling interpreter,以改善字节码分派性能。
这里的“尾调用”是 CPython 解释器内部的实现技术,并不表示 Python 函数获得了尾递归优化。因此,以下函数仍然受到递归深度限制:
def recurse(n):
if n == 0:
return 0
return recurse(n - 1)
11. Free-threaded 稳定 ABI(PEP 803 等)
Python 3.15 为 free-threaded 构建加入新的稳定 ABI,通常称为 abi3t。
这让完成适配的 C 扩展可以构建兼容多个未来 free-threaded Python 版本的二进制包,而不必为每个 Python 小版本分别编译。
常见 ABI 标记包括:
| ABI | 用途 |
| --- | --- |
| abi3 | 传统带 GIL 构建的稳定 ABI |
| cp315t | 仅面向 CPython 3.15 free-threaded 构建 |
| abi3t | 面向 free-threaded 构建的稳定 ABI |
扩展迁移到 abi3t 通常需要修改 C API 使用方式和模块导出机制。并非所有扩展都适合使用稳定 ABI;无法迁移的扩展仍可以分别构建 abi3 和 cp315t 版本。
这项改进不表示 Python 3.15 默认完全移除了 GIL,而是进一步完善了 free-threaded Python 的扩展生态。
四、类型系统
Python 3.15 包含多项类型系统增强。
TypedDict 支持带类型的额外字段(PEP 728)
类型定义可以进一步约束未显式列出的额外键,而不必把所有未知字段都视为完全动态的值。
TypeForm(PEP 747)
TypeForm 用于标注“类型表达式本身”,方便编写接收或返回类型形式的 API,并让类型检查器更准确地验证这些调用。
互斥基类(PEP 800)
类型系统可以表达彼此不相交的基类,帮助静态类型检查器:
- 判断不可能成立的类型组合;
- 检测不合理的多重继承;
- 更准确地识别不可达分支;
- 改善类型收窄。
这些特性的实际可用程度还取决于 mypy、Pyright 等类型检查器的版本和实现进度。
五、标准库与启动配置
新增 math.integer 模块(PEP 791)
标准库新增面向整数参数的数学函数模块:
from math import integer
它把整数数学运算与主要面向浮点数的 math 接口区分开来。
新增 .start 启动配置文件(PEP 829)
过去,.pth 文件中以 import 开头的行可以在 Python 启动时执行任意代码,因此较难审计启动阶段究竟执行了什么。
Python 3.15 引入 .start 文件,使用更明确的入口点格式配置启动代码:
package.module:callable
Python 启动时会定位并调用指定的无参数 callable。
需要注意:
.pth中用于扩展sys.path的路径行仍然有效;.pth中的import执行方式已被静默弃用;- 如果存在匹配的
.start文件,.pth中的import行会被忽略。
bytearray.take_bytes()
新增 bytearray.take_bytes(),可以从可变字节缓冲区中取出 bytes,避免常见的额外复制和清空操作。
旧写法:
data = bytes(buffer)
buffer.clear()
新写法:
data = buffer.take_bytes()
它适用于:
- 网络协议解析;
- 数据缓冲;
- 编码和解码;
- 压缩处理;
- 需要把可变缓冲区转换为不可变
bytes的场景。
其他标准库改进
以下模块均有不同程度的功能、性能或易用性改进:
argparse;asyncio;dataclasses;json;pdb;sqlite3;typing;venv;base64;csv;unittest;http.server;tarfile;ssl。
Python C API 还增强了对解释器结束阶段的保护,降低扩展模块在解释器 finalization 期间访问无效状态的风险(PEP 788)。
六、错误信息和终端体验
更友好的 AttributeError 提示
Python 3.15 可以识别更多来自其他编程语言的常见方法名误用。
[1, 2, 3].push(4)
可能提示:
AttributeError: 'list' object has no attribute 'push'.
Did you mean '.append'?
再例如:
"hello".toUpperCase()
可能建议使用:
"hello".upper()
当用户误用嵌套对象的属性时,错误信息还可能建议通过内部成员访问:
Did you mean '.inner.area' instead of '.area'?
当在不可变类型上调用可变容器方法时,解释器也能给出更明确的提示。
更多彩色输出
颜色支持扩展到了多个交互界面和标准库命令行工具,包括:
python --help;argparse;pdb;unittest;sqlite3;timeit;json.tool;tokenize;- PyREPL 自动补全;
- 不可传播异常提示。
默认交互式 shell 的补全项目还可以根据对象类型显示不同颜色。可以使用 PYTHON_BASIC_COMPLETER 回退到基础补全器,颜色行为也可以通过相关环境变量控制。
七、迁移注意事项
升级到 Python 3.15 时,建议重点检查以下内容。
1. 检查依赖系统默认编码的代码
以前在 Windows 等环境中依赖本地代码页的程序,在 Python 3.15 中可能因为默认 UTF-8 而改变行为。
推荐明确指定编码:
open(path, encoding="utf-8")
如果确实需要区域编码:
open(path, encoding="locale")
2. 不要假定 frozendict 是 dict 的子类
以下判断不会接受 frozendict:
isinstance(value, dict)
如果 API 接受任意只读映射,建议改用:
from collections.abc import Mapping
isinstance(value, Mapping)
3. 谨慎启用全局延迟导入
延迟导入会改变模块顶层代码的执行时机。依赖导入副作用的程序需要重点测试,例如:
- 插件注册;
- 日志初始化;
- monkey patch;
- 模块导入时修改全局状态;
- 依赖导入顺序的代码。
可以先只对部分模块使用显式 lazy import,而不是立即全局启用。
4. 检查 .pth 文件中的可执行代码
如果项目或安装工具使用 .pth 文件中的 import 行执行启动逻辑,应规划迁移到 .start 文件。
5. C 扩展需要检查 ABI 和结束阶段行为
扩展作者应检查:
- 是否需要支持
abi3t; - 是否正确适配 free-threaded 构建;
- 是否保留 frame pointer 编译参数;
- 是否会在解释器 finalization 阶段调用不安全的 C API;
- 构建工具是否已支持新的 ABI 标记。
6. 关注已删除和弃用的 API
Python 3.15 删除了一批此前已经弃用的标准库及 C API,同时新增了计划在 Python 3.16、3.17 及以后版本删除的项目。升级前应运行测试,并查看弃用警告:
python -Wd -m pytest
八、总结
对普通 Python 开发者影响最大的变化
- 使用
lazy import缩短大型应用启动时间; - 使用内置
frozendict表达不可变映射; - 使用内置
sentinel表达缺失值或特殊状态; - 在推导式中使用
*和**解包; - 默认文本编码统一为 UTF-8;
- 使用新的低开销采样分析器;
- 获得更友好的报错和终端输出。
对底层及性能开发者影响最大的变化
- JIT 编译器显著升级;
- Windows 64 位版本采用尾调用解释器;
- free-threaded 构建获得稳定 ABI
abi3t; - 默认保留 frame pointer;
- C API 增强解释器结束阶段保护;
- 原生扩展构建和分发方式进一步适配 free-threaded Python。
参考资料
- Python 3.15:What’s New 官方文档
- Python 3.15 官方文档
- PEP 790:Python 3.15 发布时间表
- PEP 810:Explicit lazy imports
- PEP 814:Add frozendict built-in type
- PEP 661:Sentinel Values
- PEP 798:Unpacking in comprehensions
- PEP 686:Make UTF-8 mode default
- PEP 799:A dedicated profiling package
- PEP 803:Stable ABI for free-threaded builds