Не смешивайте яблоки и апельсины
Проблема
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
.