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

为何==运算符在所有比较魔术方法返回NotImplemented时不报错?如何阻止类间==比较?

为什么==有默认 fallback 而其他比较运算符没有?

这个差异其实是Python对不同运算符语义的设计决定的:

  • 对于==和!=:Python认为“对象是否相等”有一个最基础的默认逻辑——对象标识(内存地址)是否相同。当双方的__eq__(或__ne__)都返回NotImplemented时,解释器会自动 fallback 到用is运算符的逻辑来判断:如果是同一个对象(内存地址相同)则返回True,否则返回False。

    结合你给的例子来看:

    1. 执行Foo() == Bar()时,先调用Foo.__eq__返回NotImplemented,接着Python尝试调用Bar.__eq__也返回NotImplemented,于是触发默认的对象标识比较——两个是不同类的实例,内存地址不同,所以返回False,因此assert not Foo() == Bar()能通过。
    2. 执行f == f时,两次调用Foo.__eq__都返回NotImplemented,此时默认逻辑检查到是同一个对象,返回True,所以断言成立。
  • 对于<、<=等排序类运算符:这类运算符的语义没有统一的“默认规则”——两个不同类的对象,谁大谁小是没有天然定义的,Python无法给出合理的默认行为,所以当双方的重载方法都返回NotImplemented时,直接抛出TypeError。

如何阻止特定类对象间的==比较?

如果不想让解释器 fallback 到对象标识比较,你需要主动在__eq__方法中抛出TypeError,而不是返回NotImplemented。比如:

class Foo:
    def __eq__(self, other):
        # 禁止和Bar实例进行==比较
        if isinstance(other, Bar):
            raise TypeError("不支持Foo和Bar实例之间的==比较")
        # 和同类型实例的自定义比较逻辑
        if isinstance(other, Foo):
            # 比如比较实例属性
            return self.__dict__ == other.__dict__
        # 其他未知类型,返回NotImplemented让Python尝试对方的__eq__
        return NotImplemented

class Bar:
    def __eq__(self, other):
        if isinstance(other, Foo):
            raise TypeError("不支持Bar和Foo实例之间的==比较")
        if isinstance(other, Bar):
            return self.__dict__ == other.__dict__
        return NotImplemented

这样当你执行Foo() == Bar()时,会直接抛出TypeError,完全阻止了比较操作,不会走到默认的对象标识判断步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:58:10