Да! Каждый раз, когда вы переопределяете __eq__
, а также хотите иметь возможность использовать объект в качестве ключа в наборе или дикте. Это особенно часто встречается в типах значений или в случаях, когда ваши объекты представляют сущности реального мира.
__hash__
вообще не хэширует переменные-члены. Для объекта без __hash__
или __eq__
он возвращает некоторое значение на основе своего внутреннего указателя. Если __eq__
определено , то вызов метода вызовет TypeError.work
Рассмотрим простой случай, когда поведение по умолчанию __eq__
и __hash__
невелико:
import getpass
class User:
def __init__(self, name):
self.name = name
def currentUser():
return User(getpass.getuser())
me = currentUser()
passwords = {}
passwords[me] = "sw0rdfish";
Это странное поведение: me == currentUser()
ложно, а passwords[currentUser()]
выдает KeyError. Поэтому, чтобы попытаться это исправить, мы определяем __eq__
:
def __eq__(self, other):
return self.name == other.name
Теперь me == currentUser()
имеет значение true, но при попытке назначить пароль выдается TypeError: unhashable type: 'User'
. Теперь мы добрались до точки, где мы хотим переопределить __hash__
:
def __hash__(self):
return hash(self.name)
И теперь он ведет себя так, как будто вы ожидаете, что любой другой такой объект будет работать, когда вы используете его в качестве ключа.