mypy与基础继承问题:子类重写__add__方法触发类型报错
解决继承场景下
__add__方法的mypy类型检查问题 问题根源
你遇到的报错是因为子类Child的__add__方法参数类型Child比父类Parent的Parent更严格,违反了里氏替换原则:父类方法能接收的参数(任意Parent实例),子类必须也能接收,否则当子类被当作父类使用时会出现类型不兼容问题。
解决方案
方案1:使用Python 3.11+的Self类型
Python 3.11引入的Self类型注解,专门用于表示方法返回调用者自身的类型,能完美适配继承场景下的类型约束:
from __future__ import annotations from dataclasses import dataclass from typing import Self @dataclass class Parent: a: int = 0 def __add__(self, other: Self) -> Self: a = self.a + other.a return self.__class__(a) @dataclass class Child(Parent): b: int = 0 def __add__(self, other: Self) -> Self: a = self.a + other.a b = self.b + other.b return self.__class__(a, b) obj1 = Child(1) obj2 = Child(1, 42) print(obj1 + obj2)
方案2:兼容Python 3.10及以下的泛型方案
如果使用Python 3.10或更早版本,可通过泛型来约束类型:
from __future__ import annotations from dataclasses import dataclass from typing import Generic, TypeVar T = TypeVar('T', bound='Parent') @dataclass class Parent(Generic[T]): a: int = 0 def __add__(self: T, other: T) -> T: a = self.a + other.a return self.__class__(a) @dataclass class Child(Parent[Child]): b: int = 0 def __add__(self: Child, other: Child) -> Child: a = self.a + other.a b = self.b + other.b return self.__class__(a, b) obj1 = Child(1) obj2 = Child(1, 42) print(obj1 + obj2)
原理说明
两种方案都确保了:
- 父类和子类的
__add__方法参数类型与自身类型一致,符合里氏替换原则 - mypy能正确推断出
__add__方法的参数和返回值类型,避免类型不兼容报错 - 完整保留了原有的OOP继承逻辑和
__add__方法的功能
内容的提问来源于stack exchange,提问作者user378147
相关产品推荐
相关产品推荐

