在Python面向对象开发中,自定义类的实例默认不支持大小比较、相等判断等操作,若需要实现这类功能,就需要手动定义对应的比较方法。很多开发者初次尝试时只实现单个比较方法,结果调用其他比较操作时就会抛出TypeError,这是因为没有掌握正确的自定义比较方法逻辑。

Python内置的比较魔术方法
Python为对象比较提供了一组内置的魔术方法,每个方法对应一种比较操作,开发者可以根据需求实现对应的方法:
__eq__(self, other):实现相等判断,对应==操作符__ne__(self, other):实现不等判断,对应!=操作符__lt__(self, other):实现小于判断,对应<操作符__le__(self, other):实现小于等于判断,对应<=操作符__gt__(self, other):实现大于判断,对应>操作符__ge__(self, other):实现大于等于判断,对应>=操作符
这些方法的返回值都应该是布尔类型,接收两个参数,第一个是实例自身self,第二个是参与比较的另一个对象other。
基础自定义比较实现示例
假设我们定义一个表示学生的类,需要根据学生的分数来比较大小,分数高的学生更大:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __eq__(self, other):
# 判断两个学生是否相等,分数相同则认为相等
if not isinstance(other, Student):
return False
return self.score == other.score
def __lt__(self, other):
# 判断当前学生是否小于另一个学生,分数低则更小
if not isinstance(other, Student):
raise TypeError("比较对象必须是Student类型")
return self.score < other.score
def __le__(self, other):
if not isinstance(other, Student):
raise TypeError("比较对象必须是Student类型")
return self.score <= other.score
def __gt__(self, other):
if not isinstance(other, Student):
raise TypeError("比较对象必须是Student类型")
return self.score > other.score
def __ge__(self, other):
if not isinstance(other, Student):
raise TypeError("比较对象必须是Student类型")
return self.score >= other.score
def __ne__(self, other):
# 不等判断可以直接基于相等判断取反
return not self.__eq__(other)
def __repr__(self):
return f"Student(name={self.name}, score={self.score})"
实现上述方法后,就可以正常对Student实例进行比较操作了:
s1 = Student("张三", 85)
s2 = Student("李四", 90)
s3 = Student("王五", 85)
print(s1 == s3) # 输出True,分数相同
print(s1 < s2) # 输出True,85小于90
print(s2 > s1) # 输出True,90大于85
print(s1 <= s3) # 输出True,85小于等于85
使用total_ordering简化实现
如果每次都要实现全部6个比较方法会非常繁琐,Python的functools模块提供了total_ordering装饰器,只需要实现__eq__方法和任意一个__lt__、__le__、__gt__、__ge__方法,装饰器就会自动补全剩下的比较方法,大大减少重复代码。
使用total_ordering重写上面的Student类:
from functools import total_ordering
@total_ordering
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __eq__(self, other):
if not isinstance(other, Student):
return False
return self.score == other.score
def __lt__(self, other):
if not isinstance(other, Student):
raise TypeError("比较对象必须是Student类型")
return self.score < other.score
def __repr__(self):
return f"Student(name={self.name}, score={self.score})"
此时同样可以支持所有比较操作:
s1 = Student("张三", 85)
s2 = Student("李四", 90)
s3 = Student("王五", 85)
print(s1 == s3) # True
print(s1 < s2) # True
print(s2 > s1) # True
print(s1 <= s3) # True
print(s1 != s2) # True
自定义比较的注意事项
类型判断要严谨
在比较方法中一定要先判断other的类型,避免和其他不相关类型的对象比较时产生不符合预期的结果,对于不支持的比较类型可以直接抛出TypeError,符合Python的内置行为。
比较逻辑要保持一致性
自定义的比较逻辑要符合数学上的比较规则,比如如果a < b为True,那么b > a也必须为True,否则会导致排序等依赖比较的操作出现异常。
不需要比较时无需实现
如果自定义的类不需要比较功能,完全不需要实现这些魔术方法,强行实现没有实际意义的比较逻辑反而会增加代码的维护成本。
注意:Python 2中还有__cmp__方法用于自定义比较,但Python 3已经完全移除了这个方法,开发时不要再使用__cmp__实现比较逻辑。
Python自定义比较__lt__functools_total_ordering比较逻辑修改时间:2026-07-12 13:42:25