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

继承list/tuple未重写__eq__时,a==b为何调用b.__eq__?

问题解析:为何ListVector() == TupleVector()会调用右操作数的__eq__

核心原因:list.__eq__对非list类型返回NotImplemented

Python运算符重载的规则是:当左操作数的__eq__方法返回NotImplemented时,解释器会尝试调用右操作数的__eq__方法,而非直接判定不相等。

你继承的list.__eq__方法逻辑如下:

  • 若比较对象是list或其子类,逐元素比较并返回布尔值
  • 若为其他类型,直接返回NotImplemented,告知Python“我无法处理该比较,试试对方的方法”

由于ListVector未重写__eq__,执行ListVector() == TupleVector()时:

  1. 先调用左方的list.__eq__,传入TupleVector实例作为other
  2. 因TupleVector继承自tuple而非list,list.__eq__返回NotImplemented
  3. Python转而调用右方的TupleVector.__eq__,该方法通过zip逐元素比较返回True,导致断言意外成功

验证逻辑

直接测试list.__eq__的返回值即可确认:

lv = ListVector((1,2,3))
tv = TupleVector((1,2,3))
print(list.__eq__(lv, tv))  # 输出: NotImplemented

这也解释了为何会看到两次TupleVector.__eq__ called:

  • 第一次TupleVector() == ListVector():直接调用TupleVector.__eq__
  • 第二次ListVector() == TupleVector():list.__eq__返回NotImplemented,触发调用TupleVector.__eq__

解决方案

要让两种向量的比较符合预期,必须为ListVector重写__eq__和__ne__,统一比较逻辑:

class ListVector(list):
    def __eq__(self, other):
        # 兼容list、tuple及自定义向量类的比较
        if isinstance(other, (list, tuple, ListVector, TupleVector)):
            return all(x == y for x, y in zip(self, other, strict=True))
        return NotImplemented
    
    def __ne__(self, other):
        return not self.__eq__(other)

此实现既保证了元素级别的相等性判断,又遵循Python运算符重载规范——对非可迭代类型返回NotImplemented,让对方继续处理比较逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:18:30