我见过类似的问题,但他们没有回答为什么python __lt__
的优先级高于__gt__
?
快速举例,让我给出一个超类和子类:
class Person(object):
id = 0
def __init__(self, name):
self.name = name
self.id = Person.id
Person.id += 1
def __str__(self):
return self.name
def __lt__(self, other):
return self.id < other.id
class SubPerson(Person):
def __gt__(self, other):
return self.name > other.name
在超类Person
中,我创建了一个__lt__
方法,根据Person self.id
进行比较。在子类SubPerson
中,我根据__gt__
创建了一个self.name
方法进行比较。
我发现如果我在列表中创建了许多SubPerson
个实例:
s1 = SubPerson('WWW'); s1.id = 14
s2 = SubPerson('XXX'); s2.id = 12
s3 = SubPerson('YYY'); s3.id = 11
s4 = SubPerson('ZZZ'); s4.id = 13
lst2 = [s2, s1, s4, s3]
lst2.sort()
print([i.__str__() for i in lst2]) # >>> ['YYY', 'XXX', 'ZZZ', 'WWW']
我发现的是:
如果在超类中定义__lt__
,那么即使您在子类中定义__gt__
,它仍将按超类中的__lt__
方法排序
但如果是相反的方法,在超类中定义__gt__
,在子类中定义__lt__
,那么它将在子类中按__lt__
排序
如果两个方法名称相同(lt
或两个gt
),显然,子类将覆盖超类,因为它应该是。
但似乎它们不同时,它遵循不同的规则:无论__lt__
定义什么。我还注意到,即使在一个班级中,如果__lt__
和__gt__
都已定义(基于不同的事情,它仍将按__lt__
方法排序)
回到我的问题,我的观察是否真实?既然我是初学者,而且我还没有阅读整篇python文档,那么有人可以指出我在文档中写出这条规则的地方。
答案 0 :(得分:7)
list.sort
仅使用<
次比较。 This is documented.
像<
这样的二元运算符将首先尝试左手操作数的方法,除非右手操作数的类是左手操作数类的子类。只有在缺少第一个方法或返回NotImplemented
时才会考虑其他操作数的方法。 <
的左侧操作数方法为__lt__
,右侧操作数的方法为__gt__
。 This is also documented.
由于所有列表元素都具有相同的类,并且__lt__
总是成功,因此只有__lt__
方法最终被调用。