Python Circle类__eq__方法未使用super()为何会触发无限递归
关于Circle类__eq__方法无限递归问题的解答
首先补充原书里基类Point的典型实现逻辑,方便理解:
import math class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def distance_from_origin(self): return math.hypot(self.x, self.y) def __eq__(self, other): return isinstance(other, Point) and self.x == other.x and self.y == other.y
你可能误解了作者的表述逻辑,作者说的“不使用super()会引发无限递归”,不是指直接删除and super().__eq__(other)这段代码会导致递归,而是指:如果你想复用基类Point的坐标相等校验逻辑,却没有用super()显式调用父类的__eq__,反而错误地直接在Circle的__eq__方法里写self == other来做全量属性比较,才会触发无限递归。
具体原因非常直观:
Python的==运算符本质就是调用左操作数的__eq__方法。如果在Circle的__eq__内部写self == other,等于在方法里又重新调用了一次Circle自己的__eq__,进入方法后又会执行到self == other的判断,就会形成无限循环,直到Python的调用栈溢出报错。
原代码里用super().__eq__(other)的写法,是显式指定调用父类Point的__eq__方法,只会校验两个实例的x、y坐标是否相等,不会触发Circle自己的__eq__逻辑,所以完全不会有递归问题。
额外补充:如果真的只是删掉and super().__eq__(other),把Circle的__eq__改成只校验半径相等,是不会出现递归问题的,只是此时两个Circle实例只要半径相同就会被判定为相等,忽略了坐标属性的差异,不符合完整的相等校验要求。
内容的提问来源于stack exchange,提问作者jgg
相关产品推荐
相关产品推荐

