Как 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 ответа:
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
iffa
иb
это один и тот же объект.если какой-либо из специальных методов возврата
NotImplemented
, Python действует так, как будто этот метод не существует.обратите внимание, что последний шаг тщательно: если ни
a
, ниb
перегрузок==
, потомa == b
Это же какa is b
.