75 votes

Comment un set([]) Python vérifie-t-il si deux objets sont égaux ? Quelles méthodes un objet doit-il définir pour personnaliser cela ?

J'ai besoin de créer un objet ou une classe "conteneur" en Python, qui garde une trace des autres objets que je définis également. L'une des exigences de ce conteneur est que si deux objets sont jugés identiques, l'un (ou l'autre) est supprimé. Ma première idée était d'utiliser une classe set([]) en tant qu'objet contenant, pour remplir cette condition.

Cependant, l'ensemble ne supprime pas l'une des deux instances d'objet identiques. Que dois-je définir pour en créer une ?

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é par x == y n'est pas la méthode appelée par l'ensemble. Qu'est-ce qui est appelé ? Quelle autre méthode dois-je définir ?

Remarque : Le Item doivent rester mutables, et peuvent changer, donc je ne peux pas fournir un modèle de __hash__() méthode. Si c'est la seule façon de procéder, alors je réécrirai pour l'utilisation de la méthode immuable Item s.

68voto

ruena Points 51

Oui, vous avez besoin d'un __hash__() -ET 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__())

29voto

eumiro Points 56644

J'ai peur que vous deviez fournir un __hash__() méthode. Mais vous pouvez le coder de manière à ce qu'il ne dépende pas des attributs mutables de votre méthode Item .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X