应使用 typing.Type[ClassName](或 Python 3.9+ 的 type[ClassName])标注参数为类本身而非实例,如工厂函数接收 User 类而非 User() 实例,配合 TypeVar 可实现泛型类型关联,避免误用 User(实例)或 type(过于宽泛)。

用 typing.Type[ClassName] 标注,表示参数是类(类型对象),不是其实例。
基础写法:Type[T] 表示“类本身”
当你希望函数接收一个类(比如用于工厂、反射或类型注册),而不是该类的实例时,应使用 typing.Type:
-
Type[Foo]表示“Foo这个类”,即Foo类型的类型对象(如Foo本身,不是Foo()) - 它等价于
type[Foo](Python 3.9+ 推荐写法,更简洁) - 注意:
Foo(未加括号)是类;Foo()是实例 —— 类型标注要和实际传入值一致
实际例子
比如一个创建实例的工厂函数:
from typing import Typeclass User: def init(self, name: str): self.name = name
def create_instance(cls: Type[User], name: str) -> User: return cls(name) # ✅ 正确:cls 是类,可调用
调用时传类,不是实例
u = create_instance(User, "Alice") # ✅
立即学习“Python免费学习笔记(深入)”;
create_instance(User(), "Alice") # ❌ 类型检查器会报错
泛型与动态类:用 TypeVar 更灵活
若函数支持任意类(且返回对应类型的实例),用 TypeVar 保持类型关联:
from typing import Type, TypeVarT = TypeVar("T", bound=object)
def build(cls: Type[T], *args, *kwargs) -> T: return cls(args, **kwargs)
类型检查器知道:build(Foo, ...) → Foo 实例;build(Bar, ...) → Bar 实例
常见误区
- ❌ 写成
cls: User:这表示参数必须是User的实例,语义完全相反 - ❌ 写成
cls: type:太宽泛,丢失具体类型信息,无法做返回值推导 - ✅ Python 3.9+ 可直接用
type[User]替代Type[User],更直观










