Ich muss in Python ein 'Container'-Objekt oder eine' Container'-Klasse erstellen, die andere Objekte aufzeichnet, die ich ebenfalls definiere. Eine Anforderung dieses Containers besteht darin, dass, wenn zwei Objekte als identisch angesehen werden, eines (eines davon) entfernt wird. Mein erster Gedanke war, a set([])
als das enthaltende Objekt zu verwenden, um diese Anforderung zu erfüllen.
Die Menge entfernt jedoch keine der beiden identischen Objektinstanzen. Was muss ich definieren, um eine zu erstellen?
Hier ist der Python-Code.
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))
Dolmetscher
>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
Es ist klar, dass das __eq__()
, was von aufgerufen wird x == y
, nicht die von der Menge aufgerufene Methode ist. Wie heißt das? Welche andere Methode muss ich definieren?
Hinweis: Das Item
s muss veränderbar bleiben und kann sich ändern, daher kann ich keine Methode bereitstellen __hash__()
. Wenn dies der einzige Weg ist, werde ich für die Verwendung von unveränderlichen Item
s umschreiben .
quelle
Antworten:
Ich fürchte, Sie müssen eine
__hash__()
Methode angeben. Aber Sie können es so codieren, dass es nicht von den veränderlichen Attributen Ihres abhängtItem
.quelle
__hash__()
nur für unveränderliche Objekte definiert werden sollte.__eq__
? Vergleichen Sie diese (1,2) Attribute? Dann müssen Sie auch in Ihrer__hash__
Methode einen Hash von (1,2) zurückgeben .hash
Sie einfach das eingebaute :hash((self.foo, self.bar))
. Hierbei wird der Tupel-Hash verwendet, der Ihren Anforderungen entspricht. (Sie__eq__
könnten auch zumtuple
Vergleich geschrieben werden.)Ja, Sie benötigen eine
__hash__()
Methode UND den Vergleichsoperator, den Sie bereits angegeben haben.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__())
quelle
__ne__
, und selbst in 2.x sollten Sie nicht__ne__
in Bezug auf definieren__eq__
. Siehe stackoverflow.com/a/30676267/5337834