
Python 3.15 低调发布:那些被头条忽略的宝藏特性
Python 3.15 beta 1 已经冻结功能。除了懒加载和 Tachyon 分析器等大特性,TaskGroup 优雅取消、上下文管理器装饰器改进、线程安全迭代器和 Counter XOR 等小特性同样值得关注。
原文来源:Jamie Chang's Blog — Python 3.15: features that didn't make the headlines — 2026 年 5 月 13 日发布。Python 3.15 官方文档参考 docs.python.org/3.15/whatsnew/3.15.html。
每到这个时候,Python 的新版本又开始向我们走来。随着 Python 3.15.0b1 功能冻结,我们已经知道了今年晚些时候会带来什么。大家的目光都在懒加载(Lazy Imports)和 Tachyon 采样分析器这些大功能上,但这些小功能同样值得关注。
Asyncio TaskGroup 优雅取消
TaskGroup 是结构化并发的一种形式,让开发者以干净的方式创建多个并发任务。以前如果要在后台等待一个信号来中断 TaskGroup 的执行,过程相当别扭:
class Interrupt(Exception):
...
with suppress(Interrupt):
async with asyncio.TaskGroup() as tg:
tg.create_task(run())
tg.create_task(run())
if await wait_for_signal():
raise Interrupt()上面的代码能工作,因为 TaskGroup 中的异常会导致其他任务被取消。自定义的 Interrupt 异常作为 ExceptionGroup 的一部分抛出,然后被 contextlib.suppress 过滤掉。
在 Python 3.15 中,TaskGroup.cancel() 让这一切变得非常简单:
async with asyncio.TaskGroup() as tg:
tg.create_task(run())
tg.create_task(run())
if await wait_for_signal():
tg.cancel()简单到不需要解释——它直接取消整个组,不抛出任何异常。
上下文管理器改进:终于能当装饰器用了
你知道吗?上下文管理器从 Python 3.3 开始就可以兼作装饰器:
@contextmanager
def duration(message: str) -> Iterator[None]:
start = time.perf_counter()
try:
yield
finally:
print(f"{message} elapsed {time.perf_counter() - start:.2f} seconds")
@duration('workload')
def workload():
...但之前有一个问题:对于异步函数和生成器,它不工作。
当你对 async def 或 def 生成器函数使用这个装饰器时,调用它们会立即返回(协程对象或生成器对象),而不是覆盖整个生命周期。这在 3.15 中被修复了——ContextDecorator 现在会检查被包装函数的类型,确保装饰器覆盖整个生命周期。
个人来看,这使上下文管理器成为创建装饰器的最佳方式。它避免了一些常见的陷阱,语法也更简洁。
线程安全迭代器
迭代器是 Python 的基础设施之一。但默认情况下,迭代器不是线程安全的。在多线程或自由线程(free-threading)环境中使用同一迭代器,可能会出现跳过值或内部状态损坏的问题。
Python 3.15 用 threading.serialize_iterator 解决了这个问题:
import threading
events = threading.serialize_iterator(stream_events(...))
with ThreadPoolExecutor() as executor:
fut1 = executor.submit(consume, events)
fut2 = executor.submit(consume, events)还有 threading.synchronized_iterator 装饰器,直接应用到生成器函数上:
@synchronized_iterator
def stream_events():
...以及 threading.concurrent_tee,它不是分割值,而是将值复制到多个迭代器中:
source1, source2 = threading.concurrent_tee(squares(10), n=2)
with ThreadPoolExecutor() as executor:
fut1 = executor.submit(consume, source1)
fut2 = executor.submit(consume, source2)以前我们需要依赖 Queue 来协调线程间的消费,有了这些工具,多线程代码的抽象层不再需要改变了。
惊喜一:Counter 的 XOR 操作
collections.Counter 是一个非常实用的类,它像 dict[KeyType, int] 一样工作,但有一堆方便的操作:
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
print(f"{c + d = }") # Counter(a=4, b=3) — 相加
print(f"{c - d = }") # Counter(a=1, b=0) — 相减(只保留正数)
print(f"{c & d = }") # Counter(a=1, b=1) — 交集:min(c[x], d[x])
print(f"{c | d = }") # Counter(a=3, b=2) — 并集:max(c[x], d[x])在 Python 3.15 中,加入了 XOR 操作:
c ^ d == Counter(a=2, b=1)
# 等于 (c | d) - (c & d)可以把它理解为集合的对称差集:出现在任一 Counter 中但不同时出现的元素。虽然实际用途可能有限,但 API 完整性是好事。
惊喜二:不可变 JSON 对象
Python 3.15 引入了 frozendict,配合 JSON 模块的新 array_hook 参数,现在可以方便地将 JSON 解析为完全不可变(可哈希)的形式:
json.loads('{"a": [1, 2, 3, 4]}',
array_hook=tuple,
object_hook=frozendict)
# 返回 frozendict({'a': (1, 2, 3, 4)})array_hook 是对 object_hook 的补充,以前 JSON 模块支持自定义对象钩子,但不支持自定义数组类型。现在两者都有了,JSON 解析的可定制性上了一个台阶。
总结
Python 3.15 并不是一个"革命性"的版本——懒加载和 Tachyon 分析器才是真正的亮点。但如果你已经熟悉那些大功能,这些"小功能"恰好是日常编码中最实用的部分。
TaskGroup.cancel()—— 异步编程更顺手了ContextDecorator的异步兼容 —— 装饰器写法更统一了threading.serialize_iterator—— 多线程迭代不再头疼- Counter XOR +
array_hook—— API 完整性和细节打磨
这些变化虽小,但每一个都是 Python 开发者在实际工作中踩过的坑。Python 3.15 beta 已经可以试用了,正式版预计下半年发布。
延伸阅读
© 2026 四月 · CC BY-NC-SA 4.0
原文链接:https://aprilzz.com/tools/python-315-hidden-features
相关文章
Open Design:Claude Design 的开源替代方案
Open Design 是 Anthropic Claude Design 的开源替代方案,支持 16 种编码 Agent、71 套品牌级设计系统,可生成交互式原型、幻灯片、图片和视频。本地优先、BYOK、可部署到 Vercel。
Semble — 为 AI Agent 量身打造的高效代码搜索工具
相比 grep+read 需要 100k token 才能达到 85% 召回率,Semble 只需 2k token 就能做到 94% 召回率,而且完全本地运行。
Needle:将 Gemini 工具调用能力蒸馏进 26M 参数模型
Cactus Compute 开源了 Needle,一个仅 26M 参数的 Function Calling 模型,从 Gemini-3.1-Flash-Lite 蒸馏而来。可在智能手机上原生运行,预填充速度达 6000 tok/s。