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.
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 ?
Lorsque Python2.x voit a == b
, il essaie ce qui suit.
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)
.type(a)
a remplacé __eq__
(c'est-à-dire que type(a).__eq__
n'est pas object.__eq__
), le résultat est a.__eq__(b)
.type(b)
a remplacé __eq__
, le résultat est b.__eq__(a)
.__cmp__
. S'il existe, les objets sont égaux si et seulement si elle retournait zero
.object.__eq__(a, b)
, qui est True
si 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
.