Объект является хэшируемым, если у него есть хэш-значение, которое никогда не меняется в течение его срока службы (для этого нужен __hash__() метод), и его можно сравнить с другими объектами (для этого нужен метод __eq__() or __cmp__()). Хэшируемые объекты, которые сравниваются равными, должны иметь одинаковое хэш-значение.
Хэшируемость делает объект пригодным для использования в качестве ключа словаря и элемента набора, потому что эти структуры данных используют значение хэша внутри.
Все неизменяемые встроенные объекты Python являются хэшируемыми, в то время как изменяемые контейнеры (такие как списки или словари) отсутствуют. Объекты, являющиеся экземплярами пользовательских классов, хэшируются по умолчанию; все они сравниваются неравнозначно, и их хэш-значение равно их id().
Ответ 2
Во всех приведенных здесь ответах содержится хорошее рабочее объяснение хэшируемых объектов в python, но я считаю, что сначала нужно понять термин "хэширование".
Хеширование - это концепция в информатике, которая используется для создания высокопроизводительных структур данных с псевдослучайным доступом, в которых необходимо хранить большой объем данных и быстро получать к нему доступ.
Например, если у вас есть 10 000 телефонных номеров, и вы хотите сохранить их в массиве (который представляет собой последовательную структуру данных, которая хранит данные в смежных ячейках памяти и обеспечивает произвольный доступ), но у вас может не быть требуемого количества смежных ячеек памяти.
Итак, вы можете вместо этого использовать массив размером 100 и использовать хэш-функцию для сопоставления набора значений с теми же индексами, и эти значения могут храниться в связанном списке. Это обеспечивает производительность, аналогичную производительности массива.
Теперь хэш-функция может быть такой же простой, как деление числа на размер массива и использование остатка в качестве индекса.
Все, что не изменяемо (изменяемый означает, с вероятностью измениться), может быть хэшировано. Помимо хэш-функции, которую нужно искать, если она есть в классе, например. dir(tuple) и в поисках __hash__ метода, вот несколько примеров
#x = hash(set([1,2])) #set unhashable x = hash(frozenset([1,2])) #hashable #x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable x = hash((1,2,3)) #tuple of immutable objects, hashable #x = hash() #x = hash({1,2}) #list of mutable objects, unhashable #x = hash([1,2,3]) #list of immutable objects, unhashable
В моем понимании, согласно глоссарию Python, когда вы создаете экземпляр объектов, которые являются хэшируемыми, неизменяемое значение также вычисляется в соответствии с элементами или значениями экземпляра. Например, это значение затем может быть использовано в качестве ключа в словаре, как показано ниже:
Мы можем обнаружить, что хэш-значение tuple_a и tuple_c одинаковы, поскольку у них одинаковые члены. Когда мы используем tuple_a в качестве ключа в dict_a, мы можем обнаружить, что значение для dict_a[tuple_c] такое же, что означает, что когда они используются в качестве ключа в словаре, они возвращают одно и то же значение, потому что значения хэша одинаковы. Для тех объектов, которые не являются хэшируемыми, метод __hash__ определяется как None:
>>> type(dict.__hash__) <class'NoneType'>
Я предполагаю, что это хэш-значение вычисляется при инициализации экземпляра, а не динамическим способом, поэтому хэшируемыми являются только неизменяемые объекты. Надеюсь, это поможет.