#python-3.x #hash #set
#python-3.x #хэш #set
Вопрос:
У меня есть 2 класса ниже. Поскольку в наборах могут храниться только хешируемые объекты, я определяю хеш-функцию для класса Person. Каждый раз, когда я добавляю Person в объект group, вызывается хэш-функция, которая генерирует хэш, используя только имя. Может ли кто-нибудь объяснить мне, почему, когда я добавляю объект p2 с тем же именем, что и p1, но разного возраста для группы, python все равно добавляет его к групповому объекту, даже если 2 объекта имеют одинаковый хэш. Разве python не должен при добавлении объекта в set проверять хэш и либо добавлять, либо заменять объект? Если я попытаюсь добавить объект p3, точно такой же, как p1 или p2, он не будет добавлен.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __hash__(self):
print(f'inhash: {self.name}, {self.age}, {hash(self.name)}')
return hash(self.name)
def __repr__(self):
return f'<Person({self.name}, {self.age})>'
class Group:
def __init__(self, group_name):
self.group_name = group_name
self.persons = set()
def add_person(self, person):
self.persons.add(person)
def __repr__(self):
return f'<Group({self.group_name}, {self.persons})>'
p1 = Person('p1', 10)
p2 = Person('p1', 20)
print("persons p1, p2, p3:", (p1, p2))
group = Group('pp')
group.add_person(p1)
print(group)
group.add_person(p2)
print(group)
Комментарии:
1. Вам необходимо реализовать
__eq__
Ответ №1:
Из документов __hash__
:
Если класс не определяет
__eq__()
метод, он также не должен определять__hash__()
операцию; если он определяет__eq__()
, но нет__hash__()
, его экземпляры не будут использоваться в качестве элементов в хешируемых коллекциях. Если класс определяет изменяемые объекты и реализует__eq__()
метод, он не должен реализовываться__hash__()
, поскольку реализация хэшируемых коллекций требует, чтобы хэш-значение ключа было неизменяемым (если хэш-значение объекта изменяется, оно будет в неправильном хэш-сегменте).
Акцент мой.
Вам также необходимо предоставить __eq__
реализацию, чтобы она могла правильно различать объекты.