Reputation: 10759
The python documentation mentions that if you override __eq__
and the object is immutable, you should also override __hash__
in order for the class to be properly hashable.
In practice, when I do this I often end up with code like
class MyClass(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __eq__(self, other):
if type(other) is type(self):
return (self.a == other.a) and (self.b == other.b)
else:
return False
def __hash__(self):
return hash((self.a, self.b))
This is somewhat repetitive, and there is a clear risk of forgetting to update one when the other is updated.
Is there a recommended way of implementing these methods together?
Upvotes: 24
Views: 20298
Reputation: 13
I think you can use user defined hash function is better.
class MyClass(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __eq__(self, other):
if type(other) is type(self):
return (self.a, self.b) == (other.a, other.b)
else:
return NotImplemented
def __hash__(self):
return hash((self.a, self.b))
Upvotes: -3
Reputation: 1
Is that the equivalent of this one-liner eq?
def __eq__(self, other):
return type(other) is type(self) and (self.a == other.a) and (self.b == other.b)
Upvotes: -1
Reputation: 10759
Answering my own question. It seems one way of performing this is to define an auxillary __members
function and to use that in defining __hash__
and __eq__
. This way, there is no duplication:
class MyClass(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __members(self):
return (self.a, self.b)
def __eq__(self, other):
if type(other) is type(self):
return self.__members() == other.__members()
else:
return False
def __hash__(self):
return hash(self.__members())
Upvotes: 34