J'ai besoin de créer un objet ou une classe "conteneur" en Python, qui conserve un enregistrement d'autres objets que je définis également. Une exigence de ce conteneur est que si deux objets sont réputés identiques, un (l'un ou l'autre) est supprimé. Ma première pensée a été d'utiliser une set([])
comme objet contenant, pour remplir cette exigence.
Cependant, l'ensemble ne supprime pas l'une des deux instances d'objet identiques. Que dois-je définir pour en créer un?
Voici le code Python.
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
Interprète
>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
Il est clair que __eq__()
, qui est appelée par x == y
, N'est pas la méthode appelée par l'ensemble. Comment s'appelle? Quelle autre méthode dois-je définir?
Remarque: Les Item
doivent rester modifiables et peuvent changer, donc je ne peux pas fournir de __hash__()
méthode. Si c'est la seule façon de le faire, je vais réécrire pour utiliser des Item
immuables
Je crains que vous n'ayez à fournir une méthode __hash__()
. Mais vous pouvez le coder comme ça, cela ne dépend pas des attributs mutables de votre Item
.
Oui, vous avez besoin d'une méthode __hash__()
- ET de l'opérateur de comparaison que vous avez déjà fourni.
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
def __hash__(self):
return hash(self.__repr__())