上書きする__eq__
場合は、常に も上書きする必要があります__hash__
。
「a == b の場合、ハッシュ (a) == ハッシュ (b) である必要があります。そうでない場合、セットと辞書は失敗します。」エリック
__hash__
オブジェクトから整数を生成するために使用されます。これは、辞書のキーまたはセットの要素をバケットに入れるために使用され、それらをより速く見つけることができます。
を上書きしない場合__hash__
、デフォルトのアルゴリズムでは、オブジェクトが同じであっても、異なるハッシュ整数が作成されます。
あなたの場合、私はこれを行います:
class Foo(object):
def __eq__(self, other):
return type(self) == type(other)
def __hash__(self):
return 1
クラスのすべてのオブジェクトは、そのクラスの他のすべてのオブジェクトと等しいため、それらはすべてセット内の同じバケット (1) にある必要があります。この方法でin
も戻りますTrue
。
次のようになり__eq__
ます。
Foo オブジェクトのみを比較する場合
def __eq__(self, other):
return self.number == other.number
Foo オブジェクトを他のオブジェクトとも比較する場合:
def __eq__(self, other):
return type(self) == type(other) and self.number == other.number
等しいアルゴリズムが異なる異なるクラスがある場合は、double-dispatchをお勧めします。
class Foo:
def __eq__(self, other):
return hasattr(other, '_equals_foo') and other._equals_foo(self)
def _equals_foo(self, other):
return self.number == other.number
def _equals_bar(self, other):
return False # Foo never equals Bar
class Bar:
def __eq__(self, other):
return hasattr(other, '_equals_bar') and other._equals_bar(self)
def _equals_foo(self, other):
return False # Foo never equals Bar
def _equals_bar(self, other):
return True # Bar always equals Bar
このようにして、a
とb
in の両方で、a == b
等しい意味を決定します。