¿Cómo se maneja __eq__ en Python y en qué orden?

Como Python no proporciona versiones izquierda / derecha de sus operadores de comparación, ¿cómo decide a qué función llamar?

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 

Esto parece llamar a ambas funciones __eq__ . Sólo estoy buscando el árbol de decisión oficial.

La expresión a a == b invoca A.__eq__ , ya que existe. Su código incluye self.value == other . Como los int no saben compararse con los de B, Python intenta invocar B.__eq__ para ver si sabe cómo compararse con un int.

Si modifica su código para mostrar qué valores se están comparando:

 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 

se imprimirá:

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

Cuando Python2.x ve a == b , intenta lo siguiente.

  • Si el type(b) es una clase de estilo nuevo, y el type(b) es una subclase de type(a) , y el type(b) ha reemplazado __eq__ , el resultado es b.__eq__(a) .
  • Si el type(a) ha reemplazado a __eq__ (es decir, el type(a).__eq__ no es object.__eq__ ), entonces el resultado es a.__eq__(b) .
  • Si el type(b) ha invalidado __eq__ , el resultado es b.__eq__(a) .
  • Si ninguno de los anteriores es el caso, Python repite el proceso buscando __cmp__ . Si existe, los objetos son iguales si devuelve zero .
  • Como último recurso, Python llama a object.__eq__(a, b) , que es True si a y b son el mismo objeto.

Si alguno de los métodos especiales devuelve No NotImplemented , Python actúa como si el método no existiera.

Tenga en cuenta el último paso con cuidado: si ni a ni b sobrecargan == , entonces a == b es lo mismo que a is b .


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