J'ai défini une classe que j'essaie de rendre malléable. En outre, il existe une énumération qui utilise les objets de cette classe en tant que valeurs de ses membres enum.Interaction d'une classe hashable avec Enum en 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")
Bien que cela fonctionne bien, je pris conscience - en décochant commentant les déclarations print
- que les __hash__
et __eq__
méthodes magiques sont invoquées pour les deux valeurs membres ENUM. Pourquoi cela est-il ainsi? Ne sont-ils pas utilisés seulement pendant les contrôles de hachage et d'égalité?
En outre, si je change la classe enum à la suivante, tout l'enfer se déchaîne.
class Property(Enum):
cool = Dummy("foo", "cool")
hot = [Dummy("bar-1", "hot-1"), Dummy("bar-2", "hot-2")]
La méthode magique __eq__
semble être appelé à l'objet Dummy
correspondant à Property.cool
et la liste correspondant à Property.hot
, comme en témoigne la sortie:
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'
Pourquoi est-ce qui se passe? Pourquoi les méthodes magiques sont-elles appelées en premier lieu, et pourquoi __eq__
est-il appelé sur un objet de classe et une liste?
Veuillez noter que ceci est seulement un exemple représentatif, et le cas réel d'utilisation fait que cette conception - enum avec des valeurs comme des listes d'objets de classe traitables - semble moins bizarre.
Cela répond à tout; Merci. Ainsi, les valeurs des membres enum ne peuvent pas être un objet mutable, comme une liste, qui n'est pas tabouable. – Shobhit
Ils peuvent être. Si la valeur n'est pas modifiable, elle ne sera pas incluse dans la table de recherche par valeur, donc essayer de la trouver par valeur fera une boucle sur les membres et vérifiera l'égalité à la place. – 3Doubloons