Python 类型注解的关键 PEP
现代 Python 类型注解由几个 PEP 逐步铺开:484 建立 typing 模块与基础写法,585 允许直接使用内置容器泛型,604 引入竖线联合类型,695 在 3.12 起提供类型参数语法。理清这条时间线,主要是为了判断某个写法在目标版本上到底能不能用。
基本信息
| PEP 484 | typing 模块与基础注解,3.5 起 |
|---|---|
| PEP 585 | 内置容器泛型写法,3.9 起 |
| PEP 604 | 竖线联合类型,3.10 起 |
| PEP 695 | 类型参数语法,3.12 起 |
典型使用场景
- 新项目:直接用内置容器泛型与竖线联合类型,写法更短
- 维护多版本兼容库:按最低支持的 Python 版本选择写法
- 迁移旧代码:把 typing 模块里的旧写法逐步替换掉
- 类型检查器选型:确认工具对目标 PEP 的支持程度
- 制定团队规范:明确采用哪一套写法并写进检查配置
版本兼容的两种做法
- 把最低支持版本抬高到 3.10 以上,直接采用新写法
- 暂时保留旧写法,或借助延迟注解求值提升兼容性
- 在库的文档里写清最低支持版本与推荐写法
- 升级最低版本时把注解统一作为一次独立改动
现代写法
现代写法
from __future__ import annotations # 延迟注解求值,缓解版本差异
def first[T](items: list[T]) -> T | None:
return items[0] if items else None写法演进对照
| 场景 | 旧写法 | 现代写法 |
|---|---|---|
| 容器泛型 | List[int] | list[int] |
| 联合类型 | Optional[str] | str | None |
| 类型参数 | 先声明 TypeVar 再用 | 函数名后直接声明类型参数 |
跨版本兼容可以配合延迟注解求值:注解在运行时不再立即求值,新旧语法混用时的报错会明显减少。
在评审中的用法:新增注解先看是否与目标版本兼容,再看它有没有说清调用者真正需要知道的信息。
类型检查的严格程度可以分级:核心模块先开严格模式,其它目录保持基本检查,再逐步提升。
同一代码库里新旧写法混杂:阅读时要在两套心智模型之间来回切换。