Получить доступ

Как связаны __eq__ и __hash__ и что значит «хешируемый объект»?

MiddleООП
Ещё спрашивают так:
  • Почему список нельзя положить в set или сделать ключом словаря?
  • Что будет, если переопределить __eq__ без __hash__?
Коротко

Хешируемый объект имеет хеш, неизменный за всё время жизни, и сравнивается через __eq__. Правило: равные объекты обязаны иметь равные хеши. Если класс переопределяет __eq__ без __hash__, Python ставит __hash__ = None — экземпляры становятся нехешируемыми.

  • list, dict, set изменяемы и нехешируемы; tuple — хешируем, если хешируемы элементы
  • Хеш считают по тем же неизменяемым полям, что и равенство: hash((self.x, self.y))
  • @dataclass(frozen=True) генерирует согласованную пару

А ещё Хеш строк рандомизируется между запусками (PYTHONHASHSEED) — защита от атак на словари

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Как словарь ищет ключ: вычисляет hash(key), по нему находит ячейку, а при совпадении хешей сравнивает через ==. Если равные объекты дают разные хеши, словарь их не найдёт.

Почему изменяемые нехешируемы. Если бы список был ключом и потом изменился, его хеш изменился бы — запись осталась бы в ячейке старого хеша и стала недоступной.

class Point:
    def __init__(self, x, y): self.x, self.y = x, y
    def __eq__(self, other):
        return isinstance(other, Point) and (self.x, self.y) == (other.x, other.y)
    def __hash__(self):
        return hash((self.x, self.y))

По умолчанию объекты сравниваются по идентичности и хешируются по id — это согласовано. Переопределили __eq__ — Python обнулил __hash__, чтобы не допустить несогласованности; нужно определить его явно.

Возвращать NotImplemented из __eq__ для чужих типов — тогда Python попробует сравнение с другой стороны.

Что хотят услышать

  • Определение хешируемости и правило.
  • Поведение при переопределении только __eq__.
  • Почему изменяемые объекты нехешируемы.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем