python 3.12 统一泛型语法,类、函数、类型别名均用方括号直接声明类型参数,无需导入 generic 或 typevar;class[t]、deft、type name[t] = ... 语义更直白,作用域隔离更严格。

Python 3.12 的泛型定义不再需要导入 Generic 或手动声明 TypeVar,类、函数、类型别名三处的泛型语法全部统一为方括号直接声明参数,语义更直白,类型检查器支持也更稳定。
class[T] 语法替代 Generic[T] 继承
旧写法必须显式继承 Generic[T] 并提前定义 TypeVar,容易漏掉继承或拼错泛型约束;新写法把类型参数直接挂到类名后,解释器和 mypy 都能原生识别。
- 3.11 及之前:
class Box(Generic[T]): ...,漏掉Generic会导致类型推导失败 - 3.12:
class Box[T]: ...,T自动成为作用域内有效的类型变量 - 多参数支持更自然:
class Pair[K, V]: ...,无需额外TypeVar('K'), TypeVar('V') - 注意:类体内仍需用
T(而非字符串"T")参与注解,否则类型检查器会报Undefined name "T"
def func[T](...) 代替 TypeVar + 注解分离
函数级泛型过去要跨两行定义 TypeVar,再在签名里重复使用,现在一行搞定,且类型变量作用域严格限定在函数内,避免命名污染。
- 旧写法:
T = TypeVar("T"); def first(items: list[T]) -> T: ... - 新写法:
def first[T](items: list[T]) -> T: ... - 函数可重载多个类型参数:
def merge[K, V](a: dict[K, V], b: dict[K, V]) -> dict[K, V]: ... - 不支持在 lambda 中使用,
lambda [T]: ...是语法错误
type Name[T] = ... 替代 TypeAlias + TypeVar 组合
类型别名过去依赖 TypeAlias 协议和外部 TypeVar,现在 type 成为软关键字,声明即生效,泛型参数自动绑定。
- 旧写法:
from typing import TypeVar, TypeAlias; T = TypeVar("T"); Point: TypeAlias = tuple[float, float] - 新写法:
type Point = tuple[float, float]; type ListOrSet[T] = list[T] | set[T] -
type声明的别名可在运行时被isinstance或get_origin正确识别(前提是目标是泛型内置容器,如list[int]) - 不能用于动态构造,
type MyList = globals()["list"][int]会报SyntaxError
真正容易被忽略的是作用域边界:类内的 [T] 和函数内的 [T] 互不干扰,但若在模块顶层用 type T = int,再写 class C[T]: ...,里面的 T 就不会覆盖顶层的 T —— 它们根本不在同一作用域。这点和旧版 TypeVar 的全局唯一性完全不同。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











