Python3中如何让类型系统识别super()创建的子类实例的子类方法
问题本质
这段代码里,子类B重写create方法时未添加类型注解,导致类型检查器无法推断super().create()返回的是B实例,仅认为是父类A的实例——而A没有do方法,因此报错。但主函数中B.create()依靠上下文推断,能正确识别返回类型为B,所以无错误提示。
解决方法
方法1:给子类create方法添加完整类型注解
给B的create方法补上和父类一致的类型标注,让类型检查器明确返回的是当前子类的实例:
from typing import Type, TypeVar T = TypeVar('T', bound='A') class A: @classmethod def create(cls: Type[T]) -> T: return cls() class B(A): def do(self): ... @classmethod def create(cls: Type[T]) -> T: obj = super().create() obj.do() # 类型检查器现在能识别obj是B类型 return obj if __name__ == '__main__': b = B.create()
方法2:显式类型转换
如果不想重复写复杂的类型注解,可以用cast强制转换类型,告诉检查器返回的是B实例:
from typing import Type, TypeVar, cast T = TypeVar('T', bound='A') class A: @classmethod def create(cls: Type[T]) -> T: return cls() class B(A): def do(self): ... @classmethod def create(cls): obj = cast(B, super().create()) obj.do() return obj if __name__ == '__main__': b = B.create()
方法3:使用Python 3.11+的Self类型
Python 3.11及以上版本支持Self类型,能更简洁地标注类方法的返回类型,无需手动定义TypeVar:
from typing import Self class A: @classmethod def create(cls) -> Self: return cls() class B(A): def do(self): ... @classmethod def create(cls) -> Self: obj = super().create() obj.do() return obj if __name__ == '__main__': b = B.create()
内容的提问来源于stack exchange,提问作者Clément Dato
相关产品推荐
相关产品推荐

