1. 泛型函数#
可以直接在函数名后使用 [T] 定义类型参数,无需显式导入 TypeVar:
</>
python
1def max[T](args: Iterable[T]) -> T: # 定义泛型函数
2 return max(args, default=None)
3
4max([1, 2, 3]) # T 自动推断为 int
5max(["a", "b"]) # T 自动推断为 str特点:
- 类型参数
T的作用域仅限于该函数。 - 支持默认类型推断,无需手动指定
[int]或[str]。
2. 泛型类#
类名后可直接声明类型参数:
</>
python
1class Box[T]:
2 def __init__(self, value: T):
3 self.value = value
4
5 def get(self) -> T:
6 return self.value
7
8int_box = Box[int](42) # 明确指定 T 为 int
9str_box = Box("hello") # 自动推断 T 为 str特点:
- 类型参数
T可用于类的方法和属性注解。 - 与传统
Generic[T]继承方式等效,但语法更简洁。
3. 类型别名(Type Aliases)#
使用 type 关键字定义泛型类型别名:
</>
python
1type Point[T] = tuple[T, T] # 泛型类型别名
2type IntList = list[int] # 非泛型别名
3
4def process(points: Point[float]) -> None: ...特点:
- 支持泛型参数(如
Point[T]),也可用于普通类型别名。 - 运行时类型为
typing.TypeAliasType,但语法更直观。
4. 高级类型参数#
PEP 695 还支持更复杂的泛型参数声明:高级类型参数
(1) 带约束的类型参数#
</>
python
1def sort[T: (str, bytes)](items: Sequence[T]) -> None: ...T只能是str或bytes。
(2) 带边界的类型参数#
</>
python
1def hash_all[T: Hashable](items: list[T]) -> list[int]:
2 return [hash(x) for x in items]T必须实现Hashable协议。
(3) 可变类型参数(TypeVarTuple)#
</>
python
1type LabeledTuple[*Ts] = tuple[str, *Ts] # *Ts 表示可变类型元组- 用于处理不定长的泛型参数(如
*args的类型标注)。
(4) 参数规格(ParamSpec)#
</>
python
1type IntFunc[**P] = Callable[P, int] # **P 表示函数参数规格- 用于泛型回调函数类型。
5. 作用域规则#
- 类型参数(如
T)仅在定义它的函数或类内部可见。 - 不能在模块全局作用域中直接使用泛型参数(需通过类型别名或类封装)。
与传统语法的对比#
| 特性 | Python 3.12 新语法 | 旧语法(3.11 及之前) |
|---|---|---|
| 泛型函数 | def max[T](...) | T = TypeVar("T"); def max(...) |
| 泛型类 | class Box[T]: ... | class Box(Generic[T]): ... |
| 类型别名 | type Point[T] = ... | Point = TypeAlias[tuple[T, T]] |
| 类型约束 | T: (str, bytes) | T = TypeVar("T", str, bytes) |
注意事项#
- 运行时类型擦除:Python 泛型仍基于类型擦除,运行时无法获取
T的具体类型。 - 工具链兼容性:
- Mypy:需最新版本(1.11+)支持 PEP 695。
- Pylint:部分版本可能误报泛型语法错误(需临时禁用检查或回退旧语法)。
总结#
Python 3.12 的泛型语法通过 [T]、type 和高级类型参数
(如 *Ts、**P)实现了更原生的泛型编程体验,同时保持了与静态类型检查器的兼容性。如需进一步优化类型检查,可结合 mypy 或 pyright 使用。