Как Python определяет приоритет операнда для ==? - PullRequest
1 голос
/ 26 февраля 2020

Сравнение list s с оператором == возвращает bool.

>>> [0,0,0] == [0,1,0]
False

Сравнение numpy массивов с оператором == возвращает другой массив, полученный в результате поэлементного сравнения.

>>> np.array([0,0,0]) == np.array([0,1,0])
array([ True, False,  True])

Если я смешиваю типы операндов, метод numpy всегда имеет приоритет.

>>> np.array([0,0,0]) == [0,1,0]
array([ True, False,  True])
>>> [0,0,0] == np.array([0,1,0])
array([ True, False,  True])

Как Python определяет, какой операнд имеет приоритет? Мой вопрос больше связан с механикой Python, чем с numpy или list.

Ответы [ 2 ]

3 голосов
/ 26 февраля 2020

Операторы расширенного сравнения всегда сначала запрашивают левый операнд (если только правый операнд не является экземпляром подкласса типа левого; здесь это не так). Если первый проверенный операнд возвращает NotImplemented (что list всегда будет делать при сравнении с numpy массивами, поскольку он не может иметь знания о них, запрограммированных в основном интерпретаторе), то второй операнд должен выполнить отраженное сравнение (которое не изменяется для __eq__).

Поскольку numpy запекла знание list в его __eq__, а list не запекало в знании numpy массивы, numpy либо идет первым и сразу использует свой собственный лог c (когда это левый операнд), либо list идет первым (когда это левый операнд), сдается, возвращая NotImplemented, затем numpy '__eq__ делает последний вызов.

Грубые внутренние элементы вызова left == right (исключая особый случай подкласса):

attempt = type(left).__eq__(left, right)
if attempt is NotImplemented:
   attempt = type(right).__eq__(right, left)
   if attempt is NotImplemented:
       attempt = False  # Specific to __eq__, if both can't compare, returns False
return attempt

Для получения полной информации, начните с NotImplemented документы и следуйте по дороге из желтого кирпича (читай: ссылки).

1 голос
/ 26 февраля 2020

В Python левый операнд всегда вычисляется перед правым операндом. Это также относится к аргументам функции.

Python использует короткое замыкание при оценке выражений, включающих операторы and или or. При использовании этих операторов Python не оценивает второй операнд, если это не необходимо для разрешения результата. Это позволяет операторам, таким как if (s != None) и (len(s) < 10): ..., работать надежно.

year % 4 == 0 and year % 100 != 0 or year % 400 == 0

...