Любой джун может сказать, что типы данных делятся на изменяемые и неизменяемые. Но 95% джунов на этот вопрос ответить не смогут:
"Почему если засунуть инстанс обычного класса (без переопределённых дандер методов) в ключ словаря, то он успешно захэшируется, если инстанс класса является изменяемым?"
Потому что этот вопрос требует знаний:
- как связаны дандеры eq и hash
- откуда у объектов по дефолту берутся дандер методы
- как эти дандеры работают
Объекты в Python фундаментально можно сравнивать по значению, и по уникальности в памяти.
Это мера выражения значения объекта
Это мера выражения уникальности объекта в памяти
Как связаны дандеры eq и hash
Так как мы обычно сравниваем объекты именно по значению, то у нас дандер методы eq и hash взаимосвязаны, потому что hash - это получение значения, а eq - это сравнение значения. То есть при переопределении метода hash нам надо обязательно переопределять eq
Откуда у объектов по дефолту берутся дандер методы
Все объекты по дефолту наследуются от object. Object содержит свои реализации dunder-методов
По дефолту, hash возвращает id объекта (адрес в памяти). Именно поэтому инстанс класса можно засунуть в ключ словаря