Я определил класс, который я пытаюсь сделать hashable. Кроме того, существует перечисление, которое использует объекты этого класса в качестве значений его членов перечисления.Взаимодействие класса hashable с Enum в Python
from enum import Enum
class Dummy(object):
def __init__(self, name, property_):
self.name = name # can only be a string
self.property = property_ # can only be a string
def __hash__(self):
# print "Hash called for ", self
# print("----")
return hash(self.property)
def __eq__(self, other):
# print "Eq called for: "
# print self
# print other
return (self.property == other.property)
def __ne__ (self, other):
return not (self == other)
def __str__(self):
return (self.name + "$" + self.property)
class Property(Enum):
cool = Dummy("foo", "cool")
hot = Dummy("bar", "hot")
Хотя это работает отлично, я заметил, - ип-Комментирование print
заявления - что __hash__
и __eq__
магические методы вызываются для двух перечисляемых значений членов. Почему это так? Разве они не используются только во время проверок хэширования и равенства?
Кроме того, если я изменю класс перечисления на следующий, все ад сломается.
class Property(Enum):
cool = Dummy("foo", "cool")
hot = [Dummy("bar-1", "hot-1"), Dummy("bar-2", "hot-2")]
__eq__
магический метод, кажется, называется для Dummy
объекта, соответствующего Property.cool
и список, соответствующий Property.hot
, как видно из вывода:
Hash called for foo$cool
----
Eq called for:
foo$cool
[<__main__.Dummy object at 0x7fd36633f2d0>, <__main__.Dummy object at 0x7fd36633f310>]
----
Traceback (most recent call last):
File "test.py", line 28, in <module>
class Property(Enum):
File "/blah/.local/lib/python2.7/site-packages/enum/__init__.py", line 237, in __new__
if canonical_member.value == enum_member._value_:
File "test.py", line 19, in __eq__
return (self.property is other.property)
AttributeError: 'list' object has no attribute 'property'
Почему это происходит? Почему в первую очередь называются магические методы, и почему __eq__
вызывает объект класса и список?
Обратите внимание, что это только типичный пример, и реальный прецедент делает этот проект - перечисление со значениями в виде списков объектов класса хэшируемых объектов - выглядит менее странным.
Это отвечает всем; Благодарю. Таким образом, значения элементов перечисления не могут быть изменчивым объектом, например списком, который не является хешируемым. – Shobhit
Они могут быть. Если значение не хешируется, оно не будет включаться в таблицу поиска по значению, поэтому попытка найти его по значению будет проходить через члены и проверять равенство вместо – 3Doubloons