Как сделать объект правильно хешируемым?

Вот мой код:

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)) 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 3! WHY? 

Почему это происходит?
1-й и 3-й объекты имеют одинаковый контент и один и тот же хэш, но len() рассказывает о 3 уникальных объектах?

Вам также необходимо определить __eq__() совместимым способом с __hash__() – в противном случае равенство будет основано на идентичности объекта.

Документация Python может оказаться полезной:

Если класс не определяет __cmp__() или __eq__() он не должен определять __hash__() ;

Вот весь код:

 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 

Функция распознает __eq__ и как таковая len равна 2.