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

Python 3.11同类返回方法的类型标注与子类兼容构造调用问题

问题解答

为什么第一个写法触发mypy报错?

你用Self标注返回类型时,mypy要求返回当前实例所属类的对象(包括子类实例),但你直接返回Integer(...),固定返回父类实例,和Self的语义不匹配,因此报错。

type(self)是完全正确的最佳实践

用type(self)调用构造函数是Python中实现「返回同类实例、兼容子类」的标准做法:

  • 当在Integer实例上调用__add__时,type(self)就是Integer,返回Integer实例;
  • 当在DerivedInteger实例上调用__add__时,type(self)自动变为DerivedInteger,返回DerivedInteger实例,完美解决子类返回类型不对的问题。

同时,mypy能识别type(self)返回的类型和Self标注完全匹配,所以不会再抛出类型错误。

额外注意事项

如果子类重写了__init__,必须确保它能兼容父类构造函数的参数,否则type(self)(...)会因参数不匹配报错。比如:

class BadDerivedInteger(Integer):
    def __init__(self, value: int, name: str) -> None:
        super().__init__(value)
        self.name = name

# 执行会报错:TypeError: __init__() missing 1 required positional argument: 'name'
BadDerivedInteger(3, "test") + BadDerivedInteger(5, "test")

这种场景下,建议在父类定义一个专门的实例创建方法(比如from_value),让子类重写该方法适配自身构造逻辑,替代直接调用type(self):

from typing import Self

class Integer:
    def __init__(self, value: int) -> None:
        self.value = value

    @classmethod
    def from_value(cls, value: int) -> Self:
        return cls(value)

    def __add__(self, other: Self) -> Self:
        return self.from_value(self.value + other.value)

class GoodDerivedInteger(Integer):
    def __init__(self, value: int, name: str = "") -> None:
        super().__init__(value)
        self.name = name

    @classmethod
    def from_value(cls, value: int) -> Self:
        return cls(value, name="default")

# 正常运行,返回GoodDerivedInteger实例
print(type(GoodDerivedInteger(3, "a") + GoodDerivedInteger(5, "b")))

内容的提问来源于stack exchange,提问作者Antonio E. Porreca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:22:53