Почему "None is None is None" return True?

Сегодня, в интервью, технический директор спросил меня, что выглядит как простой вопрос,

Что возвращает этот оператор? :

None is None is None

Я думал, что Python выполнил первую операцию None is None и вернет True. После этого он будет сравнивать True is None который вернет False. Но, к моему удивлению, правильный ответ - True. Я пытаюсь найти ответ на этот вопрос, но после нескольких дней поиска я ничего не нашел. Может кто-нибудь объяснить, почему это происходит?

Ответы

Ответ 1

Байт-код показывает, что здесь выполняются два сравнения с дублированием середины:

>>> import dis
>>> def a():
...     return None is None is None
... 
>>> dis.dis(a)
  2           0 LOAD_CONST               0 (None)
              3 LOAD_CONST               0 (None)
              6 DUP_TOP
              7 ROT_THREE
              8 COMPARE_OP               8 (is)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_CONST               0 (None)
             17 COMPARE_OP               8 (is)
             20 RETURN_VALUE
        >>   21 ROT_TWO
             22 POP_TOP
             23 RETURN_VALUE

Как указано в документах для сравнения, это связано с тем, что эти операторы соединяются вместе.

a op b op c будет переведен в a op b and b op c (примечание b дублируется в байт-коде, как показано выше)

Ответ 2

Как некоторые люди комментируют, сравнения Python могут быть связаны цепями.

Для объяснения, когда цепочка, Python фактически ANDs выражает.

Обоснованием этого является то, что выражения, подобные a < b < c имеют общепринятую в математике интерпретацию. Следовательно, путаница вашего конкретного выражения None is None is None где задействованы операторы identy.

Таким образом, в основном это означало бы:

(None is None) and (None is None)

что явно True

Вот еще один пример в документах Python

Дальнейшая информация

Тем более, что это был вопрос интервью, важно отметить, что это не общее поведение, распространенное среди всех языков.

Как указано в документации, которую я связывал,

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

Итак, рассмотрим выражение 10 > x > 2 (так is оператор недействителен в C).

C (из-за приоритета оператора)

((10 > x) > 2)

Перевод на Python

(10 > x) and (x > 2)

Ответ 3

is является оператор сравнения, как показано в документации:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"

Так что, как и другие операторы сравнения, его можно скопировать произвольно. Так

a = b = c = None
a is b is c

эквивалентно

(a is b) and (b is c)