类属性和方法参数必须显式标注类型,否则类型检查器(如mypy)将其视为Any;实例属性需在类体顶部声明或在__init__中用self.name: str = name标注;__init__不应有返回类型注解,而__new__必须标注为-> Self;泛型类需实际使用类型变量,如items: list[T],且实例化时应指定具体类型如Stack[int]()。

类属性和方法参数必须显式标注,否则类型检查器会忽略
Python 的 typing 模块不会自动推断类中变量或方法的类型。哪怕你写了 def __init__(self, name): self.name = name,name 仍被视为 Any。类型检查器(如 mypy)只信任显式标注。
实操建议:
- 所有实例属性在
__init__中赋值前,需在类体顶部用name: str这类语句声明(PEP 526 风格),或在__init__中用self.name: str = name - 方法参数、返回值必须标注,包括
self(它应标为Self或当前类名,而非Any) - 避免只给参数标注而漏掉返回值——
def get_id(self) -> int:比def get_id(self):更可靠
使用 Self 替代硬编码类名,避免继承时类型失效
写 def clone(self) -> User: 看似合理,但子类调用时返回类型仍是 User,不是子类本身。这会导致类型检查误报或丢失多态性。
正确做法是导入并使用 Self(Python 3.11+)或 from typing import TypeVar; Self = TypeVar('Self', bound='User')(旧版本):
立即学习“Python免费学习笔记(深入)”;
from typing import Self
class User:
def __init__(self, name: str) -> None:
self.name: str = name
def clone(self) -> Self:
new = self.__class__.__new__(self.__class__)
new.name = self.name
return new
这样 Admin().clone() 的返回类型就是 Admin,不是 User。
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
__init__ 不应有返回类型注解,但 __new__ 必须标注
__init__ 的作用是初始化已创建的对象,它总是返回 None,即使你写了 -> None 也属冗余;而 __new__ 负责构造实例,必须标注返回类型,否则类型检查器无法确认返回对象是否属于当前类。
常见错误现象:
- 给
__init__加-> User:mypy 会警告“__init__should return None” - 漏标
__new__:类型检查器可能将返回值视为Any,后续调用方法时报错 - 标注
__new__时用了-> object:应写-> Self或-> 'ClassName'
泛型类需用 Generic[T] 声明,且 T 必须在类定义中实际使用
仅写 class Stack(Generic[T]): 不够,如果类里没出现 T(比如没声明 items: list[T]),mypy 会报错“Generic[T] used without parameters”。
实操要点:
- 泛型参数必须出现在类属性、方法签名或父类继承列表中(如
class ConfigurableDict(dict[str, T]):) - 若需多个泛型参数,用逗号分隔:
class Pair(Generic[K, V]): - 避免在类内部用
typing.Any替代泛型——它会绕过类型约束,失去泛型意义
泛型类的真正难点不在写法,而在实例化时是否传入具体类型参数。不写 Stack[int]() 而直接用 Stack(),很多检查器会退化为宽松模式,容易掩盖问题。

















