python .sort()的__lt__优先级高于__gt__?

时间:2018-01-18 03:19:06

标签: python python-3.x sorting oop

我见过类似的问题,但他们没有回答为什么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文档,那么有人可以指出我在文档中写出这条规则的地方。

1 个答案:

答案 0 :(得分:7)

list.sort仅使用<次比较。 This is documented.

<这样的二元运算符将首先尝试左手操作数的方法,除非右手操作数的类是左手操作数类的子类。只有在缺少第一个方法或返回NotImplemented时才会考虑其他操作数的方法。 <的左侧操作数方法为__lt__,右侧操作数的方法为__gt__This is also documented.

由于所有列表元素都具有相同的类,并且__lt__总是成功,因此只有__lt__方法最终被调用。