Каков результат возврата NotImplemented
от __eq__
специальный метод в python 3 (хорошо 3.5, если это имеет значение)?Возврат NotImplemented от __eq__
Документация нечеткая; only relevant text I found лишь отдаленно относится к «какой-либо другой запасной вариант»:
Когда
NotImplemented
возвращается, интерпретатор будет пытаться отраженную операцию на другом типе, или какой-либо другой запасной вариант, в зависимости от оператора. Если все предпринятые операции возвращаютNotImplemented
, интерпретатор поднимет соответствующее исключение. См. Implementing the arithmetic operations для получения более подробной информации.
К сожалению, в ссылке «Подробнее» не упоминается __eq__
.
Мое чтение этого отрывка говорит о том, что код ниже должен поднять «соответствующее исключение», но это не делает:
class A:
def __eq__(self, other):
return NotImplemented
class B:
def __eq__(self, other):
return NotImplemented
# docs seems to say these lines should raise "an appropriate exception"
# but no exception is raised
a = A()
b = B()
a == b # evaluates as unequal
a == a # evaluates as equal
От экспериментируя, я думаю, что когда NotImplemented
возвращается из __eq__
, интерпретатор ведет себя как если бы __eq__
не был определен в первую очередь (в частности, он сначала свопит аргументы, и если это не решит проблему, оно сравнивается с использованием по умолчанию __eq__
, который оценивает «равный», если оба объекта имеют одинаковый идентификатор) , Если это так, где в документации можно найти подтверждение этого поведения?
Edit: см Python issue 28785
Чтобы повысить исключение, вам понадобится 'raise NotImplementedError' в вашем коде. – furas
в моем Python 3 оцениваются как неравные. Поместите 'print (" A.eq ")' и 'print (" A.eq ")' и посмотрите, что происходит. Сначала называется «A.eq», позже «B.eq». И позже, вероятно, называется «eq» в другом типе данных, который может сравнивать его и возвращает результат - поэтому он не вызывает ошибки. Вероятно, он сравнивает «id (A())» и «id (B())». – furas
'id()' может работать с любыми объектами, поэтому вы не получите ошибку. '__add__' не имеет какого-либо универсального метода, который всегда работает, поэтому он может создавать исключение. – furas