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

Python继承类中运算符重载时如何选择正确对象类型?

动态派生类实例化的运算符重载解决方案

问题场景

基类实现

定义了带运算符重载的Vector基类,__add__方法返回Vector对象,运行正常:

class Vector():
    def __init__(self, vector):
        self.vector = vector
        self.length = len(vector)

    ## 通用方法
    def output(self):
        return f"{self.__class__.__name__} {self.vector} {self.compute()}"

    ## 类特定方法
    def compute(self):
        return self.vector[0]  # 返回一维向量的长度

    ## 运算符重载
    def __add__(self, summand):
        d = []
        for i in range(self.length):
            d.append(self.vector[i] + summand.vector[i])
        return Vector(d)  # 硬编码返回基类实例

a = Vector([1])
b = Vector([2])
c = a + b
print(a.output())
print(b.output())
print(c.output())

输出符合预期:

Vector [1] 1
Vector [2] 2
Vector [3] 3

派生类问题

继承Vector的Vector2类重写了compute方法,但相加后返回的是Vector对象,导致compute结果错误:

class Vector2(Vector):
    def __init__(self, vector):
        super().__init__(vector)

    ## 重写类特定方法
    def compute(self):
        return self.vector[0] * self.vector[1]  # 返回二维向量的面积

d = Vector2([1,2])
e = Vector2([4,3])
f = e + d
print(d.output())
print(e.output())
print(f.output())

输出:

Vector2 [1, 2] 2
Vector2 [4, 3] 12
Vector [5, 5] 5  ## 预期应为25

现有方案缺陷

  • 将运算符重载代码复制到派生类:违反代码复用原则,维护成本高,已弃用。
  • 在基类运算符重载中判断类名返回对应对象:新增派生类时需修改基类,扩展性差,不满意。

解决方案:动态实例化当前类

修改基类的__add__方法,用self.__class__替代硬编码的Vector,动态创建与调用者同类型的对象:

def __add__(self, summand):
    d = []
    for i in range(self.length):
        d.append(self.vector[i] + summand.vector[i])
    return self.__class__(d)  # 使用当前实例的类构造新对象

修改后重新运行派生类代码,输出符合预期:

Vector2 [1, 2] 2
Vector2 [4, 3] 12
Vector2 [5, 5] 25

原理说明

self.__class__指向当前实例所属的类,当Vector2实例调用__add__时,self.__class__就是Vector2,因此新对象自动继承该类的所有重写方法。这种方式无需修改基类即可支持后续新增的派生类,完全符合代码复用和扩展性要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:50:29