Незмінний означає, що об'єкт не зміниться суттєво протягом усього свого життя. Це неясна, але поширена ідея в мовах програмування.
Хешабельність дещо інша і стосується порівняння.
hashable Об'єкт є hashable, якщо він має хеш-значення, яке ніколи не змінюється протягом свого життя (йому потрібен__hash__()
метод), і його можна порівняти з іншими об'єктами (йому потрібен__eq__()
або__cmp__()
метод). Хеш-об'єкти, які порівнюють рівні, повинні мати однакове хеш-значення.
Усі визначені користувачем класи мають __hash__
метод, який за замовчуванням просто повертає ідентифікатор об'єкта. Отже, об’єкт, який відповідає критеріям хешируемості, не обов’язково є незмінним.
Об'єкти будь-якого нового класу, який ви оголошуєте, можуть використовуватися як ключ словника, якщо ви не запобігаєте цьому, наприклад, кидаючи з __hash__
Можна сказати, що всі незмінні об'єкти можна хешувати, тому що якщо хеш змінюється протягом життя об'єкта, то це означає, що об'єкт мутував.
Але не зовсім. Розглянемо кортеж, який має список (змінний). Деякі кажуть, що кортеж незмінний, але в той же час він дещо не розмивається (кидає).
d = dict()
d[ (0,0) ] = 1
d[ (0,[0]) ] = 1
Хашируемость і незмінність стосуються екземплярів об'єкта, а не типу. Наприклад, об'єкт типу кортеж може бути хеш-функцією чи ні.
HashMap
стає зламаним, якщо ви модифікуєте об’єкт, що використовується в ньому як ключ: не можна знайти ні старий, ні новий ключ, хоча якщо ви надрукуєте карту, його можна побачити там.