Рекомендуемый способ реализации __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)
Другие вопросы по тегам