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,原因是:
- 先调用
a.__eq__(b),返回NotImplemented; - 接着Python调用
b.__eq__(a),b的__eq__判断a不是Attribut2实例,返回NotImplemented; - 当双方的
__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
相关产品推荐
相关产品推荐

