Страница docs.python.org
в Python «Модель данных» сообщает , что когда обе стороны в операции буквального сравнения реализуют магические c методы для операции, метод левый операнд используется с правым операндом в качестве аргумента:
x<y
вызовов x.__lt__(y)
, x<=y
вызовов x.__le__(y)
, x==y
вызовов x.__eq__(y)
, x!=y
звонки x.__ne__(y)
, x>y
звонки x.__gt__(y)
и x>=y
звонки x.__ge__(y)
.
Следующий класс охватывает builtin
tuple
и реализует маги c метод для одного из этих операторов сравнения, чтобы продемонстрировать это:
class eqtest(tuple):
def __eq__(self, other):
print('Equivalence!')
При использовании экземпляров этого класса в левой части оператора сравнения он ведет себя как ожидалось:
>>> eqtest((1,2,3)) == (1,2,3)
Equivalence!
Однако оператор сравнения пользовательского класса, кажется, вызывается даже при использовании только его экземпляра справа:
>>> (1,2,3) == eqtest((1,2,3))
Equivalence!
Результат также заметно отличается, когда метод magi c левого операнда явно называется:
>>> (1,2,3).__eq__(eqtest2((1,2,3)))
True
Это легко понять и почему это может быть преднамеренным выбором дизайна, особенно с подклассами, для возврата результата, который, скорее всего, будет полезен из типа, который был определен позже. Однако, поскольку он довольно явно отклоняется от базового c документированного поведения, довольно трудно понять, как и почему он работает таким образом, достаточно уверенно, чтобы учесть и использовать его в производстве.
В чем В случаях, когда язык Python и эталонная реализация CPython меняют порядок операторов сравнения, даже если обе стороны предоставляют действительные результаты, и где это задокументировано?