Это работает, потому что int.__eq__(<something>)
возвращается NotImplemented
и когда это произойдет, это приводит к вызову other.__eq__(self)
и это то, что возвращается True
и False
здесь.
Демо:
class Derived(int):
def __eq__(self, other):
print self, other
print int.__eq__(other)
print other.__eq__(self)
return int.__eq__(other)
>>> Derived(12) == 12.0
12 12.0
NotImplemented
True
True
>>> Derived(12) == 13.0
12 13.0
NotImplemented
False
False
От NotImplemented
Docs «s:
Особое значение, которое должно быть возвращено бинарными специальными методами (например __eq__()
, __lt__()
, __add__()
, __rsub__()
, и т. д.) до указывают, что операция не выполняется в отношении другой тип; могут быть возвращены двоичными специальными методами in-place (например, __imul__()
, __iand__()
и т. д.) с той же целью. Его истинное значение имеет значение .
Примечание При NotImplemented
возвращается, интерпретатор будет пытаться отраженная операцию на другом типе, или какой-либо другой резервный, в зависимости от оператора. Если все предпринятые операции возвращают NotImplemented, интерпретатор поднимет соответствующее исключение.
Что происходит, когда оба __eq__
возвращение NotImplemented
?
Поведение отличается в Python 2 и 3.
В Python 2 она падает обратно в __cmp__
метод первого и целые числа имеют __cmp__
method in Python 2. Он удален в Python 3.
В соответствии с Python 2 Docs, если ничего не найдено, что в конечном итоге возвращается к сравнению идентичности:
Если нет __cmp__()
, __eq__()
или __ne__()
операции определяются, класс экземпляров сравниваются по идентификатору объекта («адрес»)
class Derived(int):
def __eq__(self, other):
print ("Inside __eq__")
return NotImplemented
def __cmp__(self, other):
print ("Inside __cmp__ finally")
return True
>>> Derived(12) == Derived(12)
Inside __eq__
Inside __eq__
Inside __cmp__ finally
False
Не давайте определим класс без каких-либо методом, определенным:
class Derived(object):
pass
>>> Derived() == Derived()
False
>>> d = Derived()
>>> d == d # Same objects.
True
У Python 3 больше нет метода __cmp__
, но он, похоже, теперь возвращается к идентичности. И, похоже, это не документировано.
# Python 3.5
>>> Derived() == Derived()
False
>>> d = Derived()
>>> d == d
True
Edited принять во внимание все аргументы для 'междунар .__ eq__' – Billy
Обновлен вопрос о включении' Derived (12) == Производная (12) 'случай – abukaj