Могу ли я использовать объект (экземпляр класса) в качестве ключа словаря в Python?
Я хочу использовать экземпляр класса в качестве ключа словаря, например:
classinstance = class()
dictionary[classinstance] = 'hello world'
Python, похоже, не может обрабатывать классы как ключ словаря, или я ошибаюсь? Кроме того, я мог бы использовать список кортежей, как [(classinstance, helloworld),...] вместо словаря, но это выглядит очень непрофессионально. У вас есть какие-нибудь идеи для решения этой проблемы?
4 ответов
ваши экземпляры должны быть hashable. The словарь python говорит нам:
объект хэшируется, если он имеет хэш-значение, которое никогда не изменяется в течение его жизни (ему нужен
__hash__()
метод), и его можно сравнить с другими объектами (ему нужен__eq__()
или__cmp__()
метод). Хэшируемые объекты, которые сравниваются равными, должны иметь одинаковое хэш-значение.Hashability делает объект пригодным для использования в качестве словарного ключа и члена набора, потому что эти данные структуры используют хэш-значение внутри.
все неизменяемые встроенный Python объектов hashable, а не изменяемые контейнеры (такие как списки или словари) являются. Объекты, являющиеся экземплярами пользовательских классов, по умолчанию хэшируются; все они сравниваются неравными, и их хэш-значение-это их id().
следующий код работает хорошо, потому что по умолчанию объект класса hashable :
Class Foo(object):
def __init__(self):
pass
myinstance = Foo()
mydict = {myinstance : 'Hello world'}
print mydict[myinstance]
выход : Привет, мир
кроме того, и для более продвинутого использования, вы должны прочитать это сообщение:
попробуйте реализовать хэш и эквалайзер методы в вашем классе.
например, вот простой хэшируемый класс словаря, который я сделал:
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__()
нет ничего плохого в использовании экземпляра в качестве словарного ключа, если он следует правила: ключ словаря должен быть неизменяемым.