如何用TypeVar修复from_dict子类返回值的MyPy类型不兼容错误?
解决子类中from_dict方法的类型提示问题
问题根源在于Statement类的from_dict方法返回类型被硬编码为Statement,导致子类调用该方法时,MyPy无法识别实际返回的是子类实例,从而抛出类型不匹配的错误。要修复这个问题,需要用TypeVar和Generic实现泛型类型推导。
步骤说明
- 定义绑定到
Statement的TypeVar,限制只能用于Statement及其子类 - 让
Statement继承Generic,使其支持泛型参数 - 修改
from_dict方法的类型提示,让它返回当前类的实例类型 - 优化
Parent类的类型定义,使其能关联具体的Statement子类类型
修改后的完整代码
from __future__ import annotations from abc import ABC from dataclasses import dataclass from typing import ClassVar, Type, TypeVar, Generic # 定义绑定到Statement的TypeVar,限制只能用于Statement及其子类 T = TypeVar('T', bound='Statement') @dataclass class Statement(ABC, Generic[T]): @classmethod def from_dict(cls: Type[T]) -> T: return cls() # 让Parent类也支持泛型,关联具体的Statement子类 S = TypeVar('S', bound=Statement) @dataclass class Parent(ABC, Generic[S]): SIGNATURE_CLS: ClassVar[Type[S]] def say(self) -> S: return self.SIGNATURE_CLS.from_dict() @dataclass class ChildStatement(Statement['ChildStatement']): pass @dataclass class Child(Parent[ChildStatement], ABC): SIGNATURE_CLS = ChildStatement def say(self) -> ChildStatement: return self.SIGNATURE_CLS.from_dict()
原理解释
TypeVar('T', bound='Statement'):创建一个只能用于Statement及其子类的类型变量,确保类型安全Statement(ABC, Generic[T]):让Statement成为泛型类,携带自身的类型信息from_dict(cls: Type[T]) -> T:通过cls: Type[T]告诉MyPy,当前类是T类型的,返回值自然也是T类型,这样子类调用时会自动推导为子类类型Parent(ABC, Generic[S]):让Parent类关联具体的Statement子类类型,say方法的返回类型也会对应到具体的子类,避免类型不匹配
内容的提问来源于stack exchange,提问作者Bram Vanroy
相关产品推荐
相关产品推荐

