__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__
since cmp(x, y)
returns -1
ifx < y
と__lt__
should returnに注意してくださいTrue
)