Почему "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)