2026 年秋天,Python 3.15 就要正式和大家见面了。眼下 RC1 已经放出,距离稳定版只差最后一步。这次升级不怎么改变你写业务逻辑代码的方式,却在启动速度、运行效率、数据安全和排错体验上,悄悄做了一堆“底层功夫”。
简单说:同样的代码,有机会跑得更快;一些以前容易踩的坑,现在能够尽量避免了。今天锋哥来好好聊聊Python这次更新。

这次升级,到底值不值得等?
启动更快:lazy import 终于转正
运行更快:JIT 又加了一档油
数据更稳:frozendict 和 sentinel
排查更轻松:Tachyon 采样分析器
编码和报错,也比以前更省心
Python 这几年一直在做两件事:一是让解释器自己变快,二是把“默认行为”改得更不容易出错。3.15 把这两条线都往前推了一步。
官方给出的数字很实在:升级后的 JIT,在 x86-64 Linux 上比标准解释器平均快大约 8%~9%;在苹果芯片上,还能再明显一点。对大多数业务代码来说,这不是“重写一遍就能快十倍”那种神话,而是你什么都不用改,升级完就能白嫖一点性能。
更香的是启动。很多项目一打开,就要把一堆库全部 import 进来,哪怕这次运行根本用不上。3.15 的懒加载导入,就是专门治这个毛病的。
以前想让程序快点起来,大家常用的办法是:把 import 塞进函数里。能用,但文件顶部一下子空了,读代码的人还得满世界找“这个模块到底从哪来的”。
3.15 加了一个很顺口的写法:在 import 前面加 lazy。声明还是写在文件最上面,真正加载却拖到第一次用的时候。
# 启动时只登记名字,不立刻读盘、不立刻执行模块顶层代码lazy import jsonlazy from pathlib import Pathprint("程序已经起来了") # 到这里,json 和 pathlib 都还没真正加载data = json.loads('{"ok": true}') # 第一次用 json,这时才加载p = Path(".") # 第一次用 Path,这时才加载print(data, p)
不想改代码也行。启动时加上 -X lazy_imports=all,或者设置环境变量 PYTHON_LAZY_IMPORTS=all,现有项目也能整包变懒。
整个过程可以理解成下面这样:

有两点要注意:lazy 只能写在模块顶层,函数里、try/except 里都不行;import * 也不支持懒加载。另外,如果模块根本不存在,报错会延迟到第一次使用时才出现。这不是坏事,但调试时心里要有数。
3.14 里的 JIT 还比较“实验”。到了 3.15,它换了新的 tracing 前端,开始按真实执行路径来记录,而不是靠猜;寄存器分配、机器码生成、原地数值运算也都补了一轮。循环多、计算密的代码,更容易吃到红利。
想试的话,用官方带 JIT 的构建,然后打开开关:
import osimport time# 命令行更常见的写法:# set PYTHON_JIT=1# python demo.pydef hot_loop(n: int) -> float:total = 0.0x = 1.0for _ in range(n):x = x * 1.000001 + 0.0001total += xreturn totalstart = time.perf_counter()print(hot_loop(5_000_000))print(f"耗时:{time.perf_counter() - start:.3f} 秒")print("JIT 开关:", os.getenv("PYTHON_JIT", "未设置"))
别指望每一段代码都能自动快一倍。官方基准里,有的场景会快很多,也有个别情况几乎没变化。更稳妥的心态是:先升级、再对热点路径测一把,有提升就留下,没提升也不亏。
Windows 官方 64 位包这次默认用上了尾调用解释器;macOS 官方安装包也默认带上了无 GIL(free-threaded)支持。底层并行这条路,3.15 也没有停。
“更快”之外,3.15 在数据安全上也补了两块大家喊了很久的拼图。

第一块是内置的 frozendict。它创建之后就不能改,键和值都可哈希时,整个字典也能拿去当别的字典的键。配置、缓存键、共享常量,终于不用再自己封装一层“假只读”了。
# 配置一旦定下来,谁都改不了config = frozendict(host="127.0.0.1", port=8080, debug=False)# 下面这行会直接报错,而不是悄悄改掉共享配置# config["port"] = 9000# 只要内容一样,顺序不同也算相等,而且可以哈希cache = {frozendict(user="alice", role="admin"): "ok",}print(config["host"])print(cache[frozendict(role="admin", user="alice")])
第二块是内置的 sentinel。以前我们写“缺省值”时,常用 None,结果函数合法返回值也可能是 None,调用方分不清“没传”还是“传了空”。现在可以做一个真正独一无二的哨兵:
MISSING = sentinel("MISSING")def get_setting(data: dict, key: str, default=MISSING):if key not in data:if default is MISSING:raise KeyError(f"缺少配置项:{key}")return defaultreturn data[key]settings = {"theme": "dark"}print(get_setting(settings, "theme"))print(get_setting(settings, "lang", default="zh-CN"))# get_setting(settings, "timeout") # 明确告诉你:这项根本没给
小改动,但写库的人会很感激:边界情况终于能说清楚了。
线上程序变慢,最怕两件事:一是加日志要重启,二是一开 profile,程序自己先慢成PPT。3.15 把分析工具收进了新的 profiling 包,其中最亮眼的是采样分析器 Tachyon。
它可以按 PID 挂到正在跑的进程上,几乎不打断业务,采样频率最高能到 100 万次/秒。想看 CPU 热点、想看谁一直占着 GIL、想给异步任务画火焰图,都能直接上手。

先写一个会吃 CPU 的小脚本,比如 app.py:
def slow_sum(n: int) -> int:total = 0for i in range(n):total += i * ireturn totalif __name__ == "__main__":print(slow_sum(8_000_000))
然后用 Tachyon 去“听诊”。本地复现、线上挂进程,两条命令就够:
# 从启动开始采样,并生成可在浏览器打开的火焰图python -m profiling.sampling run --mode cpu --flamegraph -o profile.html app.py# 挂到已经在跑的进程上,弹出类似 top 的实时界面python -m profiling.sampling attach --live 12345
cProfile 还在,只是换了个更整齐的家:profiling.tracing。老代码不用急着改。真要说体验升级,Tachyon 更像给生产环境准备的“听诊器”——先看清哪一段在烧时间,再决定动哪一块。
从 3.15 开始,Python 默认按 UTF-8 读写文件,不再跟着操作系统区域设置走。Windows 上打开一份带中文的文本,少了很多“我本地好好的,服务器一跑就乱码”的故事。
# 不再依赖系统默认编码,中文、emoji 都按 UTF-8 处理with open("hello.txt", "w") as f:f.write("你好,Python 3.15 🚀")with open("hello.txt") as f:print(f.read())
如果你必须保留旧行为,可以设 PYTHONUTF8=0,或者启动时加 -X utf8=0。新项目建议还是显式写 encoding="utf-8",新旧版本都能躺平。
报错信息也更像“会说话的同事”了。从别的语言转过来的人,以前写 [1, 2, 3].push(4),只会被一句 AttributeError 噎住。现在它会直接提醒你:是不是想用 append?
推导式也更顺手了。嵌套列表想拍平,不用再写两层 for:
groups = [[1, 2], [3, 4], [5]]flat = [*xs for xs in groups] # [1, 2, 3, 4, 5]dicts = [{"a": 1}, {"b": 2}, {"a": 3}]merged = {**d for d in dicts} # {"a": 3, "b": 2},后面的覆盖前面的
这些都不是什么“新语法炫技”,就是日常写着写着,会少骂两句的那种改进。
2026年,锋哥又开始收Python+AI大模型学员了!目前活动,送AI编程+Java编程 VIP
最近锋哥录制了一些AI编程视频教程

高清视频+源码+领取。
扫描下方公众号【小锋学AI 】回复:888,
可获取下载链接
👇👇👇
👆长按上方二维码 2 秒 回复「888」即可获取