Могу ли я использовать объект (экземпляр класса) в качестве ключа словаря в Python? - PullRequest
11 голосов
/ 26 сентября 2011

Я хочу использовать экземпляр класса в качестве словарного ключа, например:

classinstance = class()
dictionary[classinstance] = 'hello world'

Кажется, что Python не может обрабатывать классы как ключ словаря, или я ошибаюсь? Кроме того, я мог бы использовать вместо словаря Tuple-list, например [(classinstance, helloworld), ...], но это выглядит очень непрофессионально. У вас есть какие-либо подсказки для решения этой проблемы?

Ответы [ 4 ]

11 голосов
/ 26 сентября 2011

Ваши экземпляры должны быть хэшируемыми. Python Glossary говорит нам:

Объект является хэшируемым, если у него есть значение хеша, которое никогда не изменяется в течение его времени жизни (ему нужен метод __hash__()), и может бытьпо сравнению с другими объектами (для этого требуется метод __eq__() или __cmp__()).Хэшируемые объекты, которые сравниваются равными, должны иметь одно и то же значение хеш-функции.

Хэш-хабильность делает объект пригодным для использования в качестве ключа словаря и члена набора, поскольку в этих структурах данных внутренне используется значение хеш-функции.

ВсеНеизменяемые встроенные объекты Python являются хэшируемыми, в то время как нет изменяемых контейнеров (таких как списки или словари).Объекты, которые являются экземплярами пользовательских классов, по умолчанию могут быть хэшируемыми;все они сравниваются неравно, и их хэш-значением является их id ().

5 голосов
/ 26 сентября 2011

Попробуйте реализовать методы hash и eq в вашем классе.

Например, вот простой класс хешируемого словаря, который я сделал:

class hashable_dict:
    def __init__(self, d):
        self.my_dict = d
        self.my_frozenset = frozenset(d.items())
    def __getitem__(self, item):
        return self.my_dict[item]
    def __hash__(self):
        return hash(self.my_frozenset)
    def __eq__(self, rhs):
        return isinstance(rhs, hashable_dict) and self.my_frozenset == rhs.my_frozenset
    def __ne__(self, rhs):
       return not self == rhs
    def __str__(self):
        return 'hashable_dict(' + str(self.my_dict) + ')'
    def __repr__(self):
        return self.__str__()
5 голосов
/ 26 сентября 2011

Следующий код работает хорошо, потому что по умолчанию ваш объект класса является хэшируемым:

Class Foo(object):
    def __init__(self):
        pass

myinstance = Foo()
mydict = {myinstance : 'Hello world'}

print mydict[myinstance]

Выход : Привет, мир

В дополнение и для более продвинутого использования, вы должны прочитать этот пост:

Объект пользовательского типа в качестве ключа словаря

3 голосов
/ 26 сентября 2011

Нет ничего плохого в том, чтобы использовать экземпляр в качестве ключа словаря при условии, что он правил : Ключ словаря должен быть неизменным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...