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

子类方法参数使用父类参数的子类触发mypy报错如何解决

报错原因

这个报错是类型系统里参数逆变规则和里氏替换原则(LSP)的强制要求:

  • 父类Getter的get方法约定了可以接收所有A类型(包括所有A的子类)的入参
  • 所有继承自Getter的子类,都必须满足「可以处理任意A类型入参」的约定
  • 你写的BGetter.get只接受B类型(比A更窄的类型),如果代码中将BGetter实例当作Getter类型使用,传入其他A子类实例时就会出现运行时错误,mypy的报错就是提前阻止这种风险。
合法解决方案

推荐使用泛型实现需求,给Getter类绑定入参类型的上界为A,子类可以指定具体的入参类型:

from abc import abstractmethod
from typing import Any, Dict, TypeVar, Generic

class A:
    a: int

class B(A):
    b: str

# 定义泛型参数,上界为A
T = TypeVar('T', bound=A)

class Getter(Generic[T]):
    @abstractmethod
    def get(self, o: T) -> Dict[str, Any]:
        pass

# 子类指定泛型参数为B
class BGetter(Getter[B]):
    def get(self, o: B) -> Dict[str, Any]:
        return {
            'a': o.a,
            'b': o.b,
        }

修改后运行mypy不会再出现报错,同时保留了完整的类型校验能力。

不推荐的绕开方案

如果你能100%确定业务中不会出现将BGetter当作Getter类型传入非B实例的场景,可以在方法上加忽略注释:

class BGetter(Getter):
    # type: ignore[override]
    def get(self, o: B) -> Dict[str, Any]:
        return {
            'a': o.a,
            'b': o.b,
        }

该方案直接绕过了mypy的override校验,存在运行时风险,仅应急使用。

内容的提问来源于stack exchange,提问作者TheEdgeOfRage

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 14:54:03