Как словарь обрабатывает объекты пользовательского класса в качестве ключей

Если my_dict уже определён как словарь, второй C(5) — другой ключ, поэтому возникнет KeyError. Без __eq__ экземпляры сравниваются по идентичности; одинаковое поле _n не делает их равными.

Короткий ответ

Что ответить на собеседовании

Если my_dict уже определён как словарь, второй C(5) — другой ключ, поэтому возникнет KeyError. Без eq экземпляры сравниваются по идентичности; одинаковое поле _n не делает их равными.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо понять, произойдёт ли проверка assert, когда в словарь my_dict помещается экземпляр собственного класса C в качестве ключа. Экземпляр создаётся дважды: при присваивании my_dict[C(5)] = 10 и при проверке assert my_dict[C(5)] == 10.

class C:
    def __init__(self, n) -> None:
        self._n = n

my_dict[C(5)] = 10
assert my_dict[C(5)] == 10

Ответ

Если my_dict уже определён как словарь, второй C(5) — другой ключ, поэтому возникнет KeyError. Без eq экземпляры сравниваются по идентичности; одинаковое поле _n не делает их равными.

Для ключей с равенством по значению нужны согласованные eq и hash. Удобный вариант:

from dataclasses import dataclass

@dataclass(frozen=True)
class C:
    n: int

my_dict = {}
my_dict[C(5)] = 10
assert my_dict[C(5)] == 10

Неизменяемость защищает хеш ключа от изменения после вставки. Если определить только eq, экземпляры обычно станут нехешируемыми. В буквальном исходном фрагменте отсутствует создание my_dict; без внешнего определения сначала возникнет NameError.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее