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
相关产品推荐
相关产品推荐

