Не смешивайте яблоки и апельсины
Проблема
Im играет с оператором __eq__ и значением NotImplemented.
Im пытается понять, что происходит, когда obj1.__eq__(obj2) возвращает NotImplemented и obj2.__eq__(obj1) также возвращает NotImplemented.
В ответ на Зачем возвращать NotImplemented вместо повышения NotImplementedError, а подробная статья Как переопределить операторы сравнения в Python в блоге LiveJournal, время выполнения должно вернуться к встроенному поведению (которое основано на идентификации для == и !=).
Пример кода
Но, попробовав пример ниже, кажется, что у меня есть несколько вызовов __eq__ для каждой пары объектов.
class Apple(object):
def __init__(self, color):
self.color = color
def __repr__(self):
return "<Apple color='{color}'>".format(color=self.color)
def __eq__(self, other):
if isinstance(other, Apple):
print("{self} == {other} -> OK".format(self=self, other=other))
return self.color == other.color
print("{self} == {other} -> NotImplemented".format(self=self, other=other))
return NotImplemented
class Orange(object):
def __init__(self, usage):
self.usage = usage
def __repr__(self):
return "<Orange usage='{usage}'>".format(usage=self.usage)
def __eq__(self, other):
if isinstance(other, Orange):
print("{self} == {other}".format(self=self, other=other))
return self.usage == other.usage
print("{self} == {other} -> NotImplemented".format(self=self, other=other))
return NotImplemented
>>> apple = Apple("red")
>>> orange = Orange("juice")
>>> apple == orange
<Apple color='red'> == <Orange usage='juice'> -> NotImplemented
<Orange usage='juice'> == <Apple color='red'> -> NotImplemented
<Orange usage='juice'> == <Apple color='red'> -> NotImplemented
<Apple color='red'> == <Orange usage='juice'> -> NotImplemented
False
Ожидаемое поведение
Ожидалось, что у меня будет только:
<Apple color='red'> == <Orange usage='juice'> -> NotImplemented
<Orange usage='juice'> == <Apple color='red'> -> NotImplemented
Затем вернемся к сопоставлению идентичности id(apple) == id(orange) → False.