必须手动实现富比较方法,否则==仅判断是否为同一对象;当类表示有明确相等或大小关系的数据(如坐标点、分数)时,需定义__eq__、__lt__等以支持逻辑比较。

Python中自定义类的比较行为,靠的是富比较方法(Rich Comparison Methods),比如 __eq__、__lt__、__le__ 等。它们不是自动继承或默认实现的,必须手动定义,否则两个实例用 == 比较时只是判断是否为同一对象(即 is),而不是按逻辑相等。
为什么要实现富比较方法
当你的类表示有明确“大小”或“相等”含义的数据(如坐标点、分数、日期、商品价格)时,直接用 ==、、<code>!= 等运算符会更自然、可读性更强。否则就得写 a.equals(b) 或 a.is_less_than(b) 这类冗长调用。
Python不会根据你实现了 __eq__ 就自动推导出 __ne__;也不会因写了 __lt__ 和 __eq__ 就自动支持 __le__。每个方法都需显式定义,或借助 functools.total_ordering 装饰器减少重复代码。
六个核心富比较方法及其对应运算符
它们都接收 self 和另一个操作数 other,返回布尔值:
立即学习“Python免费学习笔记(深入)”;
本系统经过多次升级改造,系统内核经过多次优化组合,已经具备相对比较方便快捷的个性化定制的特性,用户部署完毕以后,按照自己的运营要求,可实现快速定制会费管理,支持在线缴费和退费功能财富中心,管理会员的诚信度数据单客户多用户登录管理全部信息支持审批和排名不同的会员级别有不同的信息发布权限企业站单独生成,企业自主决定更新企业站信息留言、询价、报价统一管理,分系统查看分类信息参数化管理,支持多样分类信息,
-
__eq__(self, other)→== -
__ne__(self, other)→!= -
__lt__(self, other)→ -
__le__(self, other)→ -
__gt__(self, other)→> -
__ge__(self, other)→>=
注意:这些方法在不支持比较时应返回 NotImplemented(不是 NotImplementedError!),以便 Python 尝试调用 other 的对应反向方法(如 a 时 <code>a.__lt__(b) 返回 NotImplemented,则尝试 b.__gt__(a))。
实用实现技巧与常见陷阱
直接手写全部六个方法容易出错且重复。推荐两种稳妥方式:
- 只实现
__eq__+__lt__,再用 @total_ordering 装饰类,它会自动补全其余四个(__le__、__gt__、__ge__、__ne__) - 在方法内部做类型检查:若
other不是同类实例,返回NotImplemented,不要抛异常或硬转类型 - 避免在
__eq__中用==递归比较自身属性(比如属性本身也重载了==),要确保逻辑终止;必要时用isinstance(other, type(self))判断后再解构比较 - 对不可变对象(如
Point),可在__eq__中直接比字段元组:return (self.x, self.y) == (other.x, other.y),简洁安全
一个完整可运行示例:二维点类
以下代码展示了带 @total_ordering 的典型写法:
from functools import total_ordering
<p>@total_ordering
class Point:
def <strong>init</strong>(self, x, y):
self.x = x
self.y = y</p><pre class="brush:php;toolbar:false;">def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __lt__(self, other):
if not isinstance(other, Point):
return NotImplemented
# 先比 x,x 相同再比 y(字典序)
return (self.x, self.y) < (other.x, other.y)使用示例
p1 = Point(1, 2) p2 = Point(1, 3) p3 = Point(1, 2)
print(p1 == p3) # True print(p1 != p2) # True print(p1 p1) # True
这个例子中,@total_ordering 让我们只写 __eq__ 和 __lt__,就支持全部六种比较,且类型安全、语义清晰。









