Dado que Python no proporciona versiones izquierda / derecha de sus operadores de comparación, ¿cómo decide 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 __eq__funciones.
Estoy buscando el árbol de decisión oficial.
fuente

__eq__solo en la instancia de algún tipo no es suficiente para que == se anule?Estoy escribiendo una respuesta actualizada para Python 3 a esta pregunta.
Generalmente se entiende, pero no siempre el caso, que
a == binvocaa.__eq__(b), otype(a).__eq__(a, b).Explícitamente, el orden de evaluación es:
bel tipo de es una subclase estricta (no el mismo tipo) deatipo de y tiene__eq__, llámelo y devuelva el valor si la comparación está implementadaatiene__eq__, llámelo y devuélvalo si se implementa la comparación,__eq__y lo tiene, luego llámelo y devuélvalo si la comparación está implementada,is.Sabemos si no se implementa una comparación si el método regresa
NotImplemented.(En Python 2,
__cmp__se buscó un método, pero quedó obsoleto y se eliminó en Python 3).Probemos el comportamiento de la primera verificación por nosotros mismos dejando que B sea subclase A, lo que muestra que la respuesta aceptada es incorrecta en este aspecto:
que solo imprime
B __eq__ calledantes de regresarFalse.¿Cómo conocemos este algoritmo completo?
Las otras respuestas aquí parecen incompletas y desactualizadas, así que actualizaré la información y le mostraré cómo podría buscar esto por sí mismo.
Esto se maneja en el nivel C.
Necesitamos mirar dos bits de código diferentes aquí: el predeterminado
__eq__para objetos de claseobjecty el código que busca y llama al__eq__método independientemente de si usa el predeterminado__eq__o uno personalizado.Defecto
__eq__Al
__eq__buscar en los documentos relevantes de la api de C , se nos muestra que__eq__es manejado portp_richcompare, que en la"object"definición de tipocpython/Objects/typeobject.cse define enobject_richcompareforcase Py_EQ:.Entonces aquí, si
self == otherregresamosTrue, de lo contrario devolvemos elNotImplementedobjeto. Este es el comportamiento predeterminado para cualquier subclase de objeto que no implemente su propio__eq__método.Como
__eq__se llamaLuego encontramos los documentos de la API C, PyObject_RichCompare función , que llama
do_richcompare.Luego vemos que la
tp_richcomparefunción, creada para el"object"definición de C, es llamada pordo_richcompare, así que veamos eso un poco más de cerca.La primera verificación en esta función es para las condiciones de los objetos que se comparan:
__eq__método,luego llame al método del otro con los argumentos intercambiados, devolviendo el valor si se implementa. Si ese método no se implementa, continuamos ...
A continuación, vemos si podemos buscar el
__eq__método del primer tipo y llamarlo. Siempre que el resultado no sea NotImplemented, es decir, esté implementado, lo devolvemos.De lo contrario, si no probamos el método del otro tipo y está ahí, lo probamos y, si se implementa la comparación, lo devolvemos.
Finalmente, obtenemos una alternativa en caso de que no se implemente para ninguno de los dos tipos.
El respaldo verifica la identidad del objeto, es decir, si es el mismo objeto en el mismo lugar en la memoria; esta es la misma verificación que para
self is other:Conclusión
En una comparación, respetamos primero la implementación de la subclase de la comparación.
Luego intentamos la comparación con la implementación del primer objeto, luego con la del segundo si no fue llamado.
Finalmente, usamos una prueba de identidad para comparar la igualdad.
fuente