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

Python中__eq__返回NotImplemented却输出False的原因及__hash__疑问

问题解答:__eq__返回NotImplemented却输出False及__hash__的作用

一、为什么__eq__返回NotImplemented但比较结果是False

最小可复现代码

class Attribut:
    def __init__(
        self,
        name: str,
        other_name: str,
    ):
        self.name: str = name
        self.other_name: str = other_name
        
    def __eq__(self, other):
        if isinstance(other, Attribut):
            return self.name == other.name and self.other_name == other.other_name
        else:
            return NotImplemented
    
    def __hash__(self):
        return 0

测试代码及结果

执行以下代码:

a = Attribut("lol", "a")
print(a==4)

预期得到NotImplemented,实际输出False。

原因解释

当自定义类的__eq__返回NotImplemented时,Python会尝试调用被比较对象的__eq__方法(即4.__eq__(a))。对于整数类型来说,它的__eq__会判断传入对象是否为整数,显然Attribut实例不是,因此返回False,这就是最终的比较结果。

补充测试验证

将类实例与另一类的实例比较:

class Attribut:
    def __init__(
        self,
        name: str,
        other_name: str,
    ):
        self.name: str = name
        self.other_name: str = other_name
        
    def __eq__(self, other):
        if isinstance(other, Attribut):
            return self.name == other.name and self.other_name == other.other_name
        else:
            return NotImplemented
    
    def __hash__(self):
        return 0

class Attribut2:
    def __init__(
        self,
        name: str,
        other_name: str,
    ):
        self.name: str = name
        self.other_name: str = other_name
        
    def __eq__(self, other):
        if isinstance(other, Attribut2):
            return self.name == other.name and self.other_name == other.other_name
        else:
            return NotImplemented
    
    def __hash__(self):
        return 1

a = Attribut("lol", "a")
b = Attribut2("lol", "b")

print(a==b)

结果依然是False,原因是:

  1. 先调用a.__eq__(b),返回NotImplemented;
  2. 接着Python调用b.__eq__(a),b的__eq__判断a不是Attribut2实例,返回NotImplemented;
  3. 当双方的__eq__都返回NotImplemented时,Python默认返回False,因为不同类型的对象默认不相等。

二、重写__hash__方法的意义

  • 支持哈希容器操作:当类的实例需要作为字典的键,或者放入集合(set)中时,必须实现__hash__方法。字典和集合依赖哈希值实现快速查找、去重等功能,没有正确的哈希方法,实例无法被这些容器正常处理。
  • 保证一致性:哈希方法需遵循规则:如果两个对象通过__eq__判断相等,它们的__hash__必须返回相同值;哈希值相同的对象不一定相等(允许哈希碰撞)。
  • 避免性能问题:你当前代码中__hash__返回固定值0,会导致所有实例哈希值相同,集合和字典的查找效率会从O(1)降到O(n),严重影响性能。正确的实现应基于__eq__中用到的属性计算哈希,比如:
    def __hash__(self):
        return hash((self.name, self.other_name))
    

内容的提问来源于stack exchange,提问作者FluidMechanics Potential Flows

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:10:30