web-dev-qa-db-fra.com

Comment __eq__ est-il traité dans Python et dans quel ordre?

Depuis Python ne fournit pas de versions gauche/droite de ses opérateurs de comparaison, comment décide-t-il quelle fonction appeler?

class A(object):
    def __eq__(self, other):
        print "A __eq__ called"
        return self.value == other
class B(object):
    def __eq__(self, other):
        print "B __eq__ called"
        return self.value == other

>>> a = A()
>>> a.value = 3
>>> b = B()
>>> b.value = 4
>>> a == b
"A __eq__ called"
"B __eq__ called"
False

Cela semble appeler les deux __eq__ les fonctions. Je cherche juste l'arbre de décision officiel.

73
PyProg

Le a == b expression appelle A.__eq__, puisqu'il existe. Son code comprend self.value == other. Puisque les int ne savent pas comment se comparer aux B, Python essaie d'invoquer B.__eq__ pour voir s’il sait comment se comparer à un int.

Si vous modifiez votre code pour indiquer les valeurs comparées:

class A(object):
    def __eq__(self, other):
        print("A __eq__ called: %r == %r ?" % (self, other))
        return self.value == other
class B(object):
    def __eq__(self, other):
        print("B __eq__ called: %r == %r ?" % (self, other))
        return self.value == other

a = A()
a.value = 3
b = B()
b.value = 4
a == b

il va imprimer:

A __eq__ called: <__main__.A object at 0x013BA070> == <__main__.B object at 0x013BA090> ?
B __eq__ called: <__main__.B object at 0x013BA090> == 3 ?
92
Ned Batchelder

Lorsque Python2.x voit a == b, il essaie ce qui suit.

  • Si type(b) est une classe de nouveau style et que type(b) est une sous-classe de type(a), et que type(b) a remplacé __eq__, alors le résultat est b.__eq__(a).
  • Si type(a) a remplacé __eq__ (c'est-à-dire que type(a).__eq__ n'est pas object.__eq__), le résultat est a.__eq__(b).
  • Si type(b) a remplacé __eq__, le résultat est b.__eq__(a).
  • Si rien de ce qui précède n'est le cas, Python répète le processus à la recherche de __cmp__. S'il existe, les objets sont égaux si et seulement si elle retournait zero.
  • Enfin, Python appelle object.__eq__(a, b), qui est Truesi a et b sont le même objet.

Si l'une des méthodes spéciales renvoie NotImplemented, Python agit comme si la méthode n'existait pas.

Notez cette dernière étape avec soin: si ni a ni b ne surchargent ==, alors a == b est identique à a is b.


De https://eev.ee/blog/2012/03/24/python-faq-equality/

55
kev