跳过正文
  1. Teches/
  2. 程序语言/
  3. python/
  4. 概念基础/

3.12泛型特性

·280 字·2 分钟
目录

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 只能是 strbytes

(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)

注意事项
#

  1. 运行时类型擦除:Python 泛型仍基于类型擦除,运行时无法获取 T 的具体类型。
  2. 工具链兼容性
    • Mypy:需最新版本(1.11+)支持 PEP 695。
    • Pylint:部分版本可能误报泛型语法错误(需临时禁用检查或回退旧语法)。

总结
#

Python 3.12 的泛型语法通过 [T]type高级类型参数 (如 *Ts**P)实现了更原生的泛型编程体验,同时保持了与静态类型检查器的兼容性。如需进一步优化类型检查,可结合 mypypyright 使用。