25 分钟
Python 进阶

紧跟最新版本:3.11–3.14 新特性精选

掌握近年版本里最值得在工作中用的新语法和新库,写出更现代的Python

  • 会用 tomllib 读取 TOML 配置
  • 理解 ExceptionGroup 与 except* 并发异常处理
  • 掌握 StrEnum、字符串去前后缀、itertools 新工具
  • 看懂并会写 PEP 695 泛型新语法与 Self/override
  • 了解 3.13 自由线程等趋势,清楚生产环境怎么选版本

先建立版本地图

Python 每年出一个小版本。摸清楚每个版本加了啥,能看懂别人写的现代代码,也能判断自己项目里能不能用。

各版本最有代表性的变化(节选)

3.9 字典并集 |、str.removeprefix/removesuffix、PEP585 泛型内建写法3.10 match/case 结构化模式匹配、带括号的多上下文管理器3.11 异常组 ExceptionGroup/except*、tomllib、Self、StrEnum,整体提速3.12 PEP695 全新泛型语法、更清晰的报错、f-string 大改造、@override3.13 实验性自由线程(no-GIL)构建、全新交互式 REPL、类型系统增强3.14 继续优化错误信息与类型推断,延迟注解成为默认

🐍工作中到底能不能用新语法?

语法能不能用,只取决于部署/运行环境的 Python 版本,不是你本机的版本。上线前用 sys.version_info 确认目标版本。公司老项目若锁定 3.10,就不能写 3.11+ 的 tomllib 和 except*。库作者通常保守兼容 1~2 个版本。新项目、脚本、数据处理以及本平台(运行在 Python 3.14)可以放心用最新特性。

tomllib:标准库终于能读 TOML(3.11+)

现代 Python 项目用 pyproject.toml 做配置。3.11 起标准库内置 tomllib,无需再装第三方库即可解析 TOML。注意它只负责读,写 TOML 仍需第三方 tomli-w。

示例代码(可运行)
💡为什么 load 要用二进制模式?

tomllib.load(文件对象) 要求以 rb 打开。TOML 统一按 UTF-8 解码,由库自己处理编码,别用文本模式打开,会踩编码坑。这是新手最容易踩的报错点。

ExceptionGroup 与 except*:一次处理多个异常(3.11+)

asyncio.gather、TaskGroup 这类并发任务里,可能好几个任务同时失败。传统 try/except 一次只能抛出一个异常,Python 3.11 加了异常组,把多个异常打包,用 except*(带星号)就能按类型分别捕获。

示例代码(可运行)
⚠️except 和 except* 的区别

普通 except 一次只匹配一个异常;except* 专门配合 ExceptionGroup,会把组里同类型的异常都处理掉,其余类型继续往下匹配。它几乎总是和 asyncio.TaskGroup 一起出现,并发章节会再次遇到。

更顺手的枚举与字符串处理

示例代码(可运行)

itertools 新工具:pairwise 与 batched

示例代码(可运行)
💡老版本怎么实现 batched?

环境低于 3.12 时可用切片生成式:[items[i:i+n] for i in range(0,len(items),n)]。理解原理后,新语法只是更省事、更不易出 off-by-one 错误。

PEP 695:更简洁的泛型与类型别名语法(3.12+)

过去写泛型得先声明 TypeVar,啰嗦还容易错。Python 3.12 起能直接用方括号声明类型参数,类型别名用 type 语句。

示例代码(可运行)

typing.Self 与 @override(3.11/3.12+)

示例代码(可运行)
🐍@override 不是给运行时看的

@override 不改变运行行为,它是写给类型检查器(mypy/pyright)和读代码的人的。一旦父类改名或删掉该方法,子类上的 @override 会立刻报错,避免「以为重写了其实没有」的隐蔽 bug,大型项目用它。

f-string 增强(3.12+)

3.12 之前 f-string 花括号里不能再用同样的引号、不能跨行、不能嵌套反斜杠;3.12 起这些限制全部放开。

示例代码(可运行)

3.13 自由线程(no-GIL)与发展趋势

3.13 提供实验性的「自由线程」构建(PEP 703),目标是逐步移除 GIL,让多线程真正并行利用多核。目前仍是实验阶段,多数第三方库还在适配,生产环境暂不盲目切换,但它代表 Python 并行计算的长期方向。同期还重写了交互式 REPL:支持多行编辑、方向键回溯历史、彩色错误信息。

ℹ️GIL 是什么?为什么重要?

GIL让同一进程同一时刻只有一个线程执行Python字节码,所以CPU密集任务用多线程提速有限,目前仍应优先多进程或C扩展;I/O密集任务才适合多线程/协程。自由线程成熟后这一局面才会改变。

选择题

读取 pyproject.toml 配置,3.11+ 标准库用 tomllib 模块。

选择题

并发场景下要分别捕获一个异常组里不同类型的异常,应使用?

选择题

PEP 695(3.12+)定义泛型类 Stack 的正确新写法是?

预测输出
print([list(b) for b in __import__("itertools").batched([1,2,3,4,5],2)])

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

list 底层是一段连续的指针数组,容量不够时整体扩容(CPython 约按 1.125 倍)。因此按下标取元素是 O(1),末尾 append 均摊 O(1),但在头部 insert(0,…) 或 pop(0) 要搬动全部元素、是 O(n)。dict/set 基于哈希表,平均查找 O(1) 但更耗内存。选对数据结构,往往比抠语法更影响性能。

挑战任务

用 batched 实现分页

简单+50 XP

要给列表数据分页展示,用 itertools.batched 实现 paginate(items, size) 就行:把序列按 size 个一组切分,每组转成 list,返回页的列表,最后一页不够 size 也没关系。

用 batched 实现分页
1 个测试用例

课后作业

版本特性自查表

中等+20 XP

整理一张表:列你当前项目跑的 Python 版本,还有这个版本能用/不能用的本节特性,给3个特性各写个最小示例跑一遍验证。

版本特性自查表
1 个测试用例