为所有比较定义 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
我有一个 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