应返回NotImplemented而非False,以支持Python反射机制;需用isinstance(other, self.__class__)检查类型兼容性,再比较属性;重写__eq__时须同步定义__hash__确保一致性。

在 Python 中,让 __eq__ 方法只对同类型对象返回有意义的比较结果(即不同类型的对象直接返回 NotImplemented,而非 False),是实现安全、符合 Python 惯例的相等性判断的关键做法。
为什么不能直接返回 False?
直接在 __eq__ 中对不同类型返回 False 会破坏 Python 的运算符反射机制。当 a == b 执行时,Python 先调用 a.__eq__(b);如果它返回 NotImplemented,解释器会尝试调用 b.__eq__(a)(若存在)。若某一方返回 False,比较就提前终止,可能导致内置类型或第三方类无法正确参与比较(比如 MyClass() == 42 返回 False,但 42 == MyClass() 可能本应由 int.__eq__ 处理并返回 NotImplemented 后失败——而你的 False 干扰了这一流程)。
正确做法:用 isinstance 检查类型,不匹配则返回 NotImplemented
在 __eq__ 中,先检查另一个对象是否为**当前类的实例**(或至少是兼容的类型),否则返回 NotImplemented:
(注意:不是 type(self) == type(other),因为这会拒绝子类实例;通常用 isinstance(other, self.__class__) 更合理)
立即学习“Python免费学习笔记(深入)”;
- 使用
isinstance(other, self.__class__)判断是否为同类或子类实例(推荐,支持继承) - 若需严格限制为同一类(禁止子类),可用
type(other) is type(self) - 确认类型后,再比较关键属性(如
self.x == other.x and self.y == other.y) - 类型不匹配时,必须返回
NotImplemented(不是False,也不是抛异常)
完整示例
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return self.x == other.x and self.y == other.y
效果:
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # True
print(p1 == (1, 2)) # NotImplemented → 最终返回 False(由解释器兜底)
print((1, 2) == p1) # 元组的 eq 不认识 Point,返回 NotImplemented → 最终 False
进阶提示:配合 __hash__ 保持一致性
如果重写了 __eq__,且对象需放入 set 或作字典键,通常也要定义 __hash__。若 __eq__ 依赖某些属性,则 __hash__ 应仅基于这些**不可变属性**计算,并确保相等对象有相同哈希值。同时,若你允许子类实例参与比较,要注意子类可能修改属性逻辑,此时可考虑将 __hash__ 设为 None(禁用哈希)以避免风险。










