You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:45:41