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