How to make an object properly hashable?
You also need to define __eq__()
in a compatible way with __hash__()
– otherwise, equality will be based on object identity.
On Python 2, it is recommended you also define __ne__
to make !=
consistent with ==
. On Python 3, the default __ne__
implementation will delegate to __eq__
for you.
Here is the the entire code :
class Hero:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name + str(self.age)
def __hash__(self):
print(hash(str(self)))
return hash(str(self))
def __eq__(self,other):
return self.name == other.name and self.age== other.age
heroes = set()
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 1
heroes.add(Hero('Lara Miheenko', 17)) # gets hash -2822451113328084695
print(len(heroes)) # gets 2
heroes.add(Hero('Zina Portnova', 16)) # gets hash -8926039986155829407
print(len(heroes)) # gets 2
The function recognises the __eq__
and as such the len is 2.
The Python documentation might be helpful:
If a class does not define a
__cmp__()
or__eq__()
method it should not define a__hash__()
operation either;