Как eq обрабатывается в Python и в каком порядке?


поскольку Python не предоставляет левые/правые версии своих операторов сравнения, как он решает, какую функцию вызывать?

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

Это, кажется, называют как __eq__ функции. Просто ищу официальное дерево решений.

2 58

2 ответа:

The a == b выражение вызывает A.__eq__, так как он существует. Его код включает в себя self.value == other. Поскольку int не знают, как сравнить себя с B, Python пытается вызвать B.__eq__ чтобы увидеть, если он знает, как сравнить себя с int.

если вы изменить свой код, чтобы показать, какие значения сравниваются:

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

он будет печатать:

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

Когда Python2.х видит a == b, он пробует следующий.

  • если type(b) - это класс нового стиля, и type(b) является наследником type(a) и type(b) переопределил __eq__, то результатом b.__eq__(a).
  • если type(a) переопределил __eq__ (то есть type(a).__eq__ не object.__eq__), то результат a.__eq__(b).
  • если type(b) переопределил __eq__, то результатом b.__eq__(a).
  • если ни один из вышеперечисленных случаев, Python повторяет процесс поиска __cmp__. Если он существует, то объекты равны, если он возвращает zero.
  • в качестве окончательного запасного варианта, Python вызывает object.__eq__(a, b), которая составляет True iff a и b это один и тот же объект.

если какой-либо из специальных методов возврата NotImplemented, Python действует так, как будто этот метод не существует.

обратите внимание, что последний шаг тщательно: если ни a, ни b перегрузок ==, потом a == b Это же как a is b.


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