Como é tratado o QE em Python e em que ordem?

Uma vez que o Python não fornece versões esquerda/direita dos seus operadores de comparação, como é que ele decide qual função ligar?

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

Isto parece chamar ambas as funções __eq__. Estou à procura da árvore de decisão oficial.

Author: PyProg, 2010-08-28

2 answers

A expressão a == b invoca A.__eq__, Uma vez que existe. O seu código inclui self.value == other. Uma vez que int's não sabem como se comparar com B's, Python tenta invocar B.__eq__ para ver se ele sabe como se comparar a um int.

Se alterar o seu código para mostrar que valores estão a ser comparados:

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

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

Irá imprimir:

A __eq__ called: <__main__.A object at 0x013BA070> == <__main__.B object at 0x013BA090> ?
B __eq__ called: <__main__.B object at 0x013BA090> == 3 ?
 79
Author: Ned Batchelder, 2018-09-18 15:40:31

Quando Python2.x sees {[[0]}, tenta o seguinte.

  • Se type(b) é uma classe de estilo novo, e type(b) é uma subclasse de type(a), e {[1] } se sobrepôs __eq__, então o resultado é b.__eq__(a).
  • Se {[3] } ultrapassou __eq__ (isto é, type(a).__eq__ não é object.__eq__), então o resultado é a.__eq__(b).
  • Se {[1] } se sobrepôs __eq__, então o resultado é b.__eq__(a).
  • Se nenhuma das anteriores for o caso, o Python repete o processo que procura __cmp__. Se existir, os objectos são iguais iff que devolve zero.
  • Como um último recurso, as chamadas de Python object.__eq__(a, b), que é True iff a e b são o mesmo objecto.

Se algum dos métodos especiais retornar NotImplemented, Python age como se o método não existisse.

Note que o último passo com cuidado: se nem a nem b sobrecargas ==, então a == b é o mesmo que a is b.


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

 52
Author: kev, 2018-03-28 11:52:17