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 导入只能出现在模块作用域,不能用于:

  • 函数或类定义内部;
  • tryexceptfinally 块;
  • 星号导入;
  • __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)

如果程序需要同时接受 dictfrozendict,推荐使用抽象映射类型判断:

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;无法迁移的扩展仍可以分别构建 abi3cp315t 版本。

这项改进不表示 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. 不要假定 frozendictdict 的子类

以下判断不会接受 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 开发者影响最大的变化

  1. 使用 lazy import 缩短大型应用启动时间;
  2. 使用内置 frozendict 表达不可变映射;
  3. 使用内置 sentinel 表达缺失值或特殊状态;
  4. 在推导式中使用 *** 解包;
  5. 默认文本编码统一为 UTF-8;
  6. 使用新的低开销采样分析器;
  7. 获得更友好的报错和终端输出。

对底层及性能开发者影响最大的变化

  1. JIT 编译器显著升级;
  2. Windows 64 位版本采用尾调用解释器;
  3. free-threaded 构建获得稳定 ABI abi3t
  4. 默认保留 frame pointer;
  5. C API 增强解释器结束阶段保护;
  6. 原生扩展构建和分发方式进一步适配 free-threaded Python。

参考资料