Рекомендуемый способ реализации __eq__ и __hash__
Документация Python упоминает, что если вы переопределите __eq__
и объект неизменен, вы также должны переопределить __hash__
для того, чтобы класс был правильно хэшируемым.
На практике, когда я делаю это, я часто получаю такой код
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))
Это несколько повторяется, и есть явный риск забыть обновить один, когда другой обновляется.
Есть ли рекомендуемый способ реализации этих методов вместе?
3 ответа
Отвечая на мой собственный вопрос. Кажется, один из способов сделать это состоит в том, чтобы определить вспомогательный __members
функция и использовать это при определении __hash__
а также __eq__
, Таким образом, нет дублирования:
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())
Я думаю, вы можете лучше использовать определяемую пользователем хеш-функцию.
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 hash(self) == hash(other)
else:
return False
def __hash__(self):
return hash((self.a, self.b))
Это эквивалент этого однострочного уравнения?
def __eq__(self, other):
return type(other) is type(self) and (self.a == other.a) and (self.b == other.b)