2013-11-30 3 views
2

Предположим, у меня есть class a, который имеет функцию __eq__(self,other). Теперь я хочу иметь словарь, где ключи являются экземплярами класса (и номерами значений, но это не должно иметь значения). Тогда я получаю сообщение об ошибке:Могут ли ключи словаря быть экземплярами класса?

unhashable type: 'a' 

В documenation он говорит, что я должен определить __eq__ и __cmp__ для того, чтобы определить __hash__, но это не представляется возможным, так как мой класс не сравнимый !!

Как это решить, люди!

редактировать: Хорошо я сделал это работает только _ эк _ и _ хэш _ метод, но я до сих пор не уверен, что если питон использует метод хеширования в в операции или _ экв _ метод (который должен быть в случае, я надеюсь)

+0

def __hash __ (self): return hash (self.value^31 & 15) – smac89

+0

что должно быть self.value be? Класс должен быть абстрактным! – varantir

+0

@varantir Вы можете просто добавить фиктивный оператор печати к '__hash__', чтобы проверить, является ли это тот, который он вызывает. Кроме того, я предлагаю вам проверить мой ответ, чтобы убедиться, что ваша хеш-функция звучит. –

ответ

0

Это работает для меня ..

>>> class A: 
...  def __init__(self): 
...    self.a = 5 
... 
>>> a = A() 
>>> d = { a:"hello"} 
>>> d[a] 
'hello' 

Вы можете использовать экземпляры классов в качестве ключей для Dict

+0

* Вы можете использовать экземпляры классов как ключи для dict * - если у них есть подходящий метод '__hash__', который ... –

1

class может быть ключевым для dict, так долго, как hashCode для class постоянен. Если в любой момент времени ключ, hashCode, для класса может измениться, то вы не сможете использовать его в качестве ключа.

Именно поэтому list не может использоваться в качестве ключа. Альтернативой для list будет использование tuple, поскольку tuples являются неизменяемыми. Опять же, если вы можете гарантировать, что hashCode не изменится, вы добры.

0

Это не прямой ответ, но может быть, он может вам помочь.

Вы можете изменить __cmp__ и поднять NotImplementedError, чтобы избежать его использования.

class SomeClass(): 
    def __init__(self): 
     pass # your init here 

    def __cmp__(self, orher): 
     raise NotImplementedError('You can not compare this') 

    def __eq__(self, other): 
     pass # Your eq here 

    def __hash__(self): 
     pass # your hash function here 

Демо:

>> s = SomeClass() 
>> s == '12' 

>> NotImplementedError: You can not compare this 
3

documentation говорит, что рядом с __hash__() он нуждается в __eq__()или (не "и" как вы предлагаете) __cmp__() метод.

Так что в вашем случае достаточно определить метод __hash__().

Смежные вопросы