为所有比较定义 class 属性

Define class attribute for all comparisons

我有一个 Python class 这样的:

@dataclass
class Person:
    name: str
    relatives: Iterable['Person']

我想对所有比较使用 name 属性,以便 Person 对象默认按字母顺序排序。因此,我像这样覆盖 __gt__() 方法(如 the documentation 中所述):

    def __gt__(self, other):
        return self.name > other.name

这实际上解决了我最初的任务,我可以做例如:

p1=Person("test1", relatives=[])
p2=Person("test2", relatives=[])
sorted([p1, p2])
Out[4]: [Person(name='test1', relatives=[]), Person(name='test2', relatives=[])]

还有这个:

p1>p2
Out[5]: False
p1<p2
Out[6]: True

我了解我不必实现所有运算符:

__lt__() and __gt__() are each other’s reflection, __le__() and __ge__() are each other’s reflection, and __eq__() and __ne__() are their own reflection.

然而,为了进行相等比较,我仍然必须显式覆盖 __eq__(other)

    def __eq__(self, other):
        return isinstance(other, Person) and self.name == other.name

有没有更简洁的方法来实现这个?我会设想一些方法来告诉口译员 'use attribute name for all comparisons!'.

如果提供 __eq__ 并且在您的情况下至少有 1 个丰富的比较是可以的,您可以使用 functools.total_ordering 装饰器,如下所示:

import functools
@functools.total_ordering
class Name:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return self.name
    def __eq__(self, other):
        return self.name == other.name
    def __gt__(self, other):
        return self.name > other.name
a = Name("a")
b = Name("b")
print(a<b)
print(a<=b)
print(b>=a)

输出

True
True
True

如果这在您的情况下不可接受,您需要准备自己的装饰器以供使用,有关装饰的讨论 class 请参阅 How to decorate a class