Python 3.12 的 type[T] 不是泛型类定义语法,仅用于类型提示中表示“类对象本身”;定义泛型类仍必须使用 Generic[T] 和 TypeVar,type[T] 不能作基类、不能用于 Generic[...] 参数,仅限注解位置使用。

Python 3.12 的 type 参数语法不是用来定义泛型类的
直接说结论:type[T] 是类型提示语法,用于标注“某个值是类型本身(即类对象)”,而不是泛型参数声明机制。它和 list[T]、dict[str, int] 这类泛型用法完全不同,也不能替代 Generic[T] 或 ParamSpec 等泛型定义工具。
常见误解是看到 type[int] 就以为能像 Rust 的 Vec 那样构造泛型类——但 Python 中它只表示“int 这个类型(而非 int 的实例)”。
定义泛型类仍必须用 Generic 和类型变量
Python 3.12 没有改变泛型类的定义方式。你依然要导入 TypeVar 和 Generic,并继承 Generic[T]:
from typing import TypeVar, Generic
<p>T = TypeVar("T")</p><p>class Stack(Generic[T]):
def <strong>init</strong>(self) -> None:
self._items: list[T] = []</p><pre class="brush:php;toolbar:false;">def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
注意:type[T] 在这里完全不适用;如果你写 class Stack(type[T]):,会直接报错 TypeError: metaclass conflict ——因为 type[T] 是一个类型提示,不是类、不是元类、更不能当基类。
-
type[T]只能出现在注解位置(如函数参数、返回值、变量声明),例如:def make_instance(cls: type[T]) -> T: ... - 泛型类的类型参数必须通过
Generic[...]显式声明,并在类体中用T等类型变量参与成员签名 - 运行时该类仍是普通类,泛型信息仅用于静态检查(mypy/pyright)和 IDE 推导
type[T] 的典型用途:接收或返回类对象
当你需要表达“这个参数是一个类型(比如 str、MyModel),而不是它的实例”,才用 type[T]:
from typing import TypeVar, Type
<p>T = TypeVar("T")</p><p>def create_instance(cls: Type[T]) -> T:
return cls()</p><h1>Python 3.12+ 允许简写为:</h1><p>def create_instance(cls: type[T]) -> T:
return cls()
</p>
这种写法和泛型类定义无关,但它常被误套用到类定义上。比如有人想写“一个能存任意类型类的容器”,可能会错误地尝试:
class ClassContainer(Generic[type[T]]): # ❌ 错误!type[T] 不是合法的泛型参数
...
这会触发 SyntaxError 或 mypy 报错 Invalid type application of generic type "type"。
容易踩的坑:混淆 type[T] 和 Type[T],以及误用位置
Type[T] 是旧式写法(已弃用),type[T] 是其等价简写,但二者都只能用于注解上下文。它们不能:
- 作为父类(
class X(type[str]):→TypeError) - 作为
Generic的参数(Generic[type[T]]→ 类型检查器拒绝) - 用于
isinstance或运行时判断(isinstance(x, type[str])语法错误) - 在
__class_getitem__中被当作泛型参数处理(它没有实现该协议)
真正需要动态绑定类型的场景(比如 ORM 的模型类工厂),得靠元类、__class_getitem__ 手动实现,或者用 typing.dataclass_transform 等高级机制——type[T] 本身不提供泛型类的运行时能力。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











