在实现类的__eq__
和__lt__
方法时,通常使用元组对要比较的值进行分组,如下所示:
@total_ordering
class Foo(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __hash__(self):
return hash((self.c, self.a, self.b))
def __eq__(self, other):
return (self.c, self.a, self.b) == (other.c, other.a, other.b)
def __lt__(self, other):
return (self.c, self.a, self.b) < (other.c, other.a, other.b)
然而,这使用了每个键的自然顺序。如果我想改变,例如,如何a
排序?
到目前为止,这是我想出的,虽然它似乎工作正常,但我想知道是否有更好的方法来解决它:
@total_ordering
class Foo(object):
def __init__(self, a, b, c):
self.a = MyA(a) # Note
self.b = b
self.c = c
def __hash__(self):
return hash((self.c, self.a, self.b))
def __eq__(self, other):
return (self.c, self.a, self.b) == (other.c, other.a, other.b)
def __lt__(self, other):
return (self.c, self.a, self.b) < (other.c, other.a, other.b)
class MyA(A):
def __hash__(self):
# ...
def __eq__(self, other):
# ...
def __lt__(self, other):
# ...
子类化A
让我可以定义我的自定义排序,并允许MyA
以其他所有方式表现得像一个常规A
的,这很好,但它似乎是浪费/不必要的冗长,特别是如果我必须为多个字段执行此操作。
编辑:根据user1320237下面的回答,这就是我想出的:
@total_ordering
class Foo(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def __hash__(self):
return hash((self.c, self.a, self.b))
def __eq__(self, other):
return (0, 0, 0) == (cmp(self.c, other.c),
cmpA(self.a, other.a),
cmp(self.b, other.b))
def __lt__(self, other):
return (0, 0, 0) > (cmp(self.c, other.c),
cmpA(self.a, other.a),
cmp(self.b, other.b))
def cmpA(a1, a2):
# ...
(注意>
in __lt__
sincecmp(x, y)
返回-1
ifx < y
和__lt__
should return True
)