🐍 Python 3.15 来了:Lazy Imports、内置 frozendict、JIT 大升级——十大亮点一文看懂
作者:布啦豆的小团队
阅读时间:约 12 分钟
关键词:Python, Python 3.15, PEP, lazy imports, frozendict, JIT, 性能优化, 新特性
🌅 开篇:Python 又双叒叕更新了
昨天照常打开 Python 官网看看有没有新版本,结果差点把咖啡洒键盘上——
Python 3.15 Beta 2 发布了!
距离 3.14 正式发布才过了不到三个月,Python 团队就马不停蹄地推出了 3.15。作为一个写了十年 Python 的老码农,我第一反应是:这次又有什么新花样值得折腾?
翻完官方 What's New 文档和一堆 PEP 提案,发现这次更新的信息量不小。今天就来给大家梳理一下,Python 3.15 到底更新了什么,哪些特性值得重点关注,哪些可以暂时忽略。
🤔 先搞清楚:这次更新的定位是什么?
Python 3.15 目前处于 Beta 2 阶段(3.15.0b2),预计 2026 年 10 月正式发布。
和以往的版本更新相比,3.15 的关键词是:启动更快、类型更强、调试更爽。
| 维度 | Python 3.14 | Python 3.15 变化 |
|---|
| 启动速度 | 标准 | Lazy Imports 大幅提升 🔥 |
| 内置类型 | dict, set, frozenset | 新增 frozendict、sentinel 🆕 |
| 类型系统 | TypedDict 基础版 | TypedDict 增强 + TypeForm + Disjoint Bases 📝 |
| 性能分析 | cProfile 为主 | 新增 profiling 包 + Tachyon 采样器 🔥 |
| JIT 编译器 | 实验性 | 大幅升级 + Windows 尾调用解释器 ⚡ |
| 默认编码 | locale-dependent | UTF-8 默认 🌍 |
| 可观测性 | 手动开启 frame pointer | 默认开启 frame pointers 📊 |
一句话总结:3.15 不是革命性版本,但每个改进都直击痛点。
📦 十大核心特性详解
1️⃣ PEP 810 — 显式延迟导入(Lazy Imports)
这是 3.15 最重磅的特性,没有之一。
痛点:Python 应用启动慢,很大原因是 import 系统——每次导入模块,Python 要找文件、读磁盘、编译字节码、执行顶层代码。依赖树深的应用启动要好几秒,即使大部分导入的代码根本用不到。
解法:新增 lazy 关键字,标记为延迟导入的模块在首次使用时才真正加载。
# 以前:导入即加载,启动慢
import json
import pathlib
import pandas
import numpy
# 现在:lazy 导入,启动快
lazy import json
lazy import pathlib
lazy from pathlib import Path
print("Starting up...") # json 和 pathlib 还没加载
data = json.loads('{"key": "value"}') # json 这里才加载
p = Path(".") # pathlib 这里才加载
全局模式(不改代码也能用):
# 命令行
python -X lazy_imports=all myapp.py
# 环境变量
PYTHON_LAZY_IMPORTS=all python myapp.py
精细控制(只让自己的模块延迟加载):
import sys
def myapp_filter(importing, imported, fromlist):
return imported.startswith("myapp.")
sys.set_lazy_imports_filter(myapp_filter)
sys.set_lazy_imports("all")
import myapp.slow_module # 懒加载(匹配过滤器)
import json # 立即加载(不匹配过滤器)
💡 人话翻译:以前 import 是"打开冰箱门把所有东西都搬出来",现在是"冰箱门上贴个清单,要什么拿什么"。启动速度提升立竿见影。
限制:
- • 只能在模块顶层使用(函数/类内部用会报 SyntaxError)
- •
from module import * 和 from __future__ import ... 不能用 lazy - • 检测类型:
types.LazyImportType
2️⃣ PEP 814 — 内置 frozendict 类型
Python 有 frozenset(不可变集合)已经很多年了,但一直没有不可变字典。每次需要不可变字典,要么用 types.MappingProxyType,要么自己实现。
3.15 终于补上了:
# 创建不可变字典
d = frozendict({"name": "Python", "version": "3.15"})
# 可以做 dict 的 key(因为不可变)
cache = {
frozendict({"action": "query"}): "result1",
frozendict({"action": "update"}): "result2",
}
# 修改会报错
d["new_key"] = "value" # TypeError: 'frozendict' object does not support item assignment
💡 人话翻译:frozendict 就是"贴了封条的冰箱"——看得见拿不着,改不了动不得。需要哈希的字典场景终于有救了。
3️⃣ PEP 661 — 内置 sentinel 类型
写库/框架时经常需要定义哨兵对象(sentinel),用来区分"用户没传参数"和"用户传了 None"。
以前的写法(千奇百怪):
_MISSING = object() # 最常见
_UNSET = type("_UNSET", (), {"__repr__": lambda s: "UNSET"})() # 最丑
3.15 的标准写法:
missing = sentinel("missing")
default = sentinel("default")
def process(value=missing):
if value is missing:
print("用户没传参数")
elif value is None:
print("用户显式传了 None")
💡 人话翻译:sentinel 就是"站岗的保安"——你没来我站着,你来了我让开。每个保安都有自己的名字,不会认错人。
4️⃣ PEP 799 — 专用性能分析包 + Tachyon 采样器
Python 的性能分析工具一直比较分散——cProfile、profile、timeit、第三方的 py-spy、scalene 各玩各的。
3.15 新增统一的 profile 包,整合所有 profiling 工具,并引入 Tachyon 高频统计采样 profiler。
# 新的统一接口
import profile
# Tachyon 采样器(低开销,适合生产环境)
with profile.tachyon():
my_function()
💡 人话翻译:以前查性能要开好几个工具箱,现在一个工具箱全搞定。Tachyon 这名字起得好——像光速一样快地找出性能瓶颈。
5️⃣ PEP 831 — 默认开启 Frame Pointers
Frame pointers 是系统级性能分析(perf、flamegraph 等)的基础。以前 Python 默认关闭,需要手动编译时加 -fno-omit-frame-pointer。
3.15 默认开启,无需任何配置就能用 perf 和火焰图分析 Python 程序。
# 以前:需要特殊编译选项
# 现在:直接用
perf record -g python myapp.py
perf report
💡 人话翻译:以前用 perf 分析 Python 要自己"开后门",现在"大门直接敞开了"。系统运维同学狂喜。
6️⃣ PEP 798 — 推导式中支持解包
列表/字典/集合推导式现在支持 * 和 ** 解包操作。
# 以前:嵌套推导或 itertools.chain
from itertools import chain
flat = list(chain.from_iterable([i for i in range(3)], [i for i in range(3, 6)]))
# 现在:直接解包
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for sub in nested for x in sub] # 这个以前就能做
# 新的解包语法
items = [(1, "a"), (2, "b"), (3, "c")]
result = [*items, (4, "d")] # 推导式中直接解包
# 字典推导式
dicts = [{"a": 1}, {"b": 2}]
merged = {**d for d in dicts} # 合并多个字典
💡 人话翻译:推导式的"拆箱"能力升级了——以前只能一层一层拆,现在可以直接把包裹撕开。
7️⃣ PEP 686 — UTF-8 成为默认编码
这是一个"早就该做"的改动。以前 Python 的 open() 默认编码取决于操作系统和 locale,Windows 上经常是 GBK,Linux 上看 locale 配置。
3.15 默认用 UTF-8:
# 以前(Windows 上可能报 UnicodeDecodeError)
with open("data.txt") as f:
content = f.read() # 编码取决于 locale
# 现在:统一 UTF-8
with open("data.txt") as f:
content = f.read() # 永远是 UTF-8
💡 人话翻译:以前在不同操作系统间传文件要操心编码,现在全世界统一说"UTF-8 语",再也不用 encoding="utf-8" 写到手软了。
8️⃣ PEP 829 — 包启动配置文件
包可以定义自己的启动配置,类似 pyproject.toml 但专注于运行时行为。
# pyproject.toml 中新增
[tool.python.startup]
# 包的启动时配置
这为包作者提供了标准化的方式来声明包的初始化行为,而不需要用户手动配置。
9️⃣ 类型系统三连击
Python 的类型系统在 3.15 中迎来了一波增强:
| PEP | 特性 | 一句话说明 |
|---|
| PEP 728 | TypedDict 增强 | 支持 typed extra items,字典类型更精确 |
| PEP 747 | TypeForm | 可以注解"类型本身"而不是"类型的实例" |
| PEP 800 | Disjoint Bases | 类型系统支持不相交基类,联合类型更灵活 |
# PEP 747: TypeForm 示例
from typing import TypeForm
def process(value: TypeForm) -> None:
# value 是一个类型,不是类型的实例
pass
process(int) # ✅
process(str) # ✅
💡 人话翻译:类型系统越来越强了。以前 Python 的类型注解是"装饰品",现在快变成"法律文书"了——虽然运行时不检查,但 IDE 和 mypy 会帮你查。
🔟 JIT 编译器大幅升级 + Windows 尾调用解释器
Python 的 JIT(Just-In-Time)编译器从 3.13 开始引入,3.14 有所改进,3.15 进行了大幅升级。
同时,Windows 64 位官方二进制包现在使用尾调用解释器(tail-calling interpreter),性能有明显提升。
| 特性 | 3.14 | 3.15 |
|---|
| JIT 编译器 | 实验性 | 大幅优化 ⚡ |
| Windows 解释器 | 传统 | 尾调用版本 🚀 |
| 适用架构 | 所有 | Windows 64 位优先 |
💡 人话翻译:JIT 从"实习生"升级为"正式员工"了。虽然还不能和 Java 的 JIT 比,但方向对了——Python 越来越快是确定的趋势。
📋 其他值得关注的更新
新增模块
| 模块 | 说明 |
|---|
math.integer | 整数相关数学函数 |
profile | 统一的性能分析包 |
标准库改进
40+ 模块获得改进,包括 asyncio、dataclasses、typing、sqlite3、http.server 等。完整列表太长就不一一列了,感兴趣的直接看官方文档。
错误信息彩色输出
Python 3.15 的错误信息现在支持彩色高亮——变量名、关键字、行号用不同颜色显示,一目了然。在终端里终于不用瞪大眼睛找错误位置了。
已移除的模块
| 模块 | 替代方案 |
|---|
ast | 部分功能合并到其他模块 |
collections.abc | 保留在 collections 中 |
ctypes | 需要时单独安装 |
datetime | 部分 API 重构 |
sre_* | re 模块内部使用 |
zipimport | 合并到 importlib |
⚠️ 升级提醒:如果你的代码用了这些被移除的模块,升级前先跑一遍测试。
🚀 升级建议
什么时候能用?
| 阶段 | 时间 | 说明 |
|---|
| Alpha | 2026年5月 | 已发布,尝鲜用 |
| Beta | 2026年6月 | 当前阶段,功能冻结 |
| RC | 2026年9月 | 候选发布,bug 修复 |
| 正式版 | 2026年10月 | 生产可用 |
值得升级吗?
| 场景 | 建议 | 理由 |
|---|
| 新项目 | ✅ 直接用 | 享受最新特性 |
| 已有项目 | ⏳ 等正式版 | Beta 阶段可能有 API 变动 |
| 生产环境 | ❌ 等 3.15.1+ | 稳定后再升级 |
| 类型注解重度使用 | ✅ 尝鲜 | TypedDict 增强 + TypeForm 很香 |
| 启动速度敏感 | ✅ 试试 lazy imports | 效果立竿见影 |
⚠️ 踩坑记录
| 坑 | 原因 | 解决 |
|---|
lazy import 在函数内报 SyntaxError | PEP 810 限制:lazy 只能在模块顶层用 | 把 lazy import 移到文件顶部 |
frozendict 不能用 d["key"] = value | 这是特性不是 bug,不可变字典 | 需要修改时创建新实例 |
| UTF-8 默认编码导致旧代码报错 | 以前依赖 locale 编码的代码 | 显式指定 encoding="utf-8" 或更新代码 |
| 部分模块被移除导致 ImportError | 3.15 移除了多个过时模块 | 查看移除列表,用替代模块 |
| Beta 版本 API 可能变动 | 功能冻结但 API 细节可能调整 | 生产环境等正式版 |
🎯 写在最后
Python 3.15 不是一个"天翻地覆"的版本,但每个改进都切中要害:
- • Lazy imports 解决了 Python 多年的启动速度痛点
- • frozendict 补全了内置类型的重要缺失
- • Frame pointers 默认开启 让性能分析变得零配置
- • JIT 升级 继续推动 Python 的性能进化
如果你问我最期待哪个特性——毫无疑问是 Lazy Imports。作为一个经常被 Python 启动速度折磨的开发者,lazy import 简直是救命稻草。
不过现在还是 Beta 阶段,建议大家先在测试环境尝鲜,等 10 月正式发布后再上生产。毕竟 Python 的版本更新传统是:.0 稳定看 .1,.1 稳定看 .2。
📎 相关资源
-
- Python 3.15 What's New
-
- PEP 810 — Lazy Imports
-
- PEP 814 — frozendict
-
- PEP 661 — sentinel
-
- PEP 799 — profiling
-
- PEP 831 — frame pointers
-
- PEP 798 — 推导式解包
-
- Python 官网下载
-
本教程由布啦豆的小团队整理,如有问题欢迎反馈。