Результат сравнения "a is a is"

A = 314

if A == A == A:
    print('True #1')

if A == A == 271:
    print('True #2')

lie = 0
if lie is lie is lie:
    print('no matter how white, how small,')
    print('how incorporating of a smidgeon')
    print('of truth there be in it.')

Результат:

True #1
no matter how white, how small,
how incorporating of a smidgeon
of truth there be in it.

Я знаю, что не нормально использовать два "=" и "есть" в предложении if. Но я хотел бы знать, как интерпретатор Python интерпретирует оператор if.

Является ли выражение lie is lie is lie интерпретировано одновременно или короткое замыкание?

Ответ 1

То, что вы пережили, называется цепочкой операторов.

Из документации по Comparisons:

Сравнение может быть скопировано произвольно, например, x < y <= zэквивалентно x < y and y <= z, за исключением того, что y оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y оказывается ложь).

Акцент на мой.

Итак, это означало бы, что lie is lie is lie интерпретируется как (lie is lie) and (lie is lie), и не более того.

В общем случае a op b op c op d ... оценивается так же, как a op b and b op c and c op d ... и так далее. Выражение анализируется в соответствии с правилами грамматики python . В частности,

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

Ответ 2

У этого вопроса уже много ответов, но рассмотрим функцию split в байт-код:

def f():
    lie = 0
    if lie is lie is lie:
        print('Lie')

dis.dis(f)

  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               0 (lie)
  3           4 LOAD_FAST                0 (lie)
              6 LOAD_FAST                0 (lie)
              8 DUP_TOP
             10 ROT_THREE
             12 COMPARE_OP               8 (is)
             14 JUMP_IF_FALSE_OR_POP    22
             16 LOAD_FAST                0 (lie)
             18 COMPARE_OP               8 (is)
             20 JUMP_FORWARD             4 (to 26)
        >>   22 ROT_TWO
             24 POP_TOP
        >>   26 POP_JUMP_IF_FALSE       36
  4          28 LOAD_GLOBAL              0 (print)
             30 LOAD_CONST               2 ('Lie')
             32 CALL_FUNCTION            1
             34 POP_TOP
        >>   36 LOAD_CONST               0 (None)
             38 RETURN_VALUE

Это говорит о том, что все lie проверяются, чтобы увидеть, соответствуют ли они линейным образом. Если кто-то терпит неудачу, он должен сломаться/вернуться.

Чтобы подтвердить, учтите:

>lie is lie is lie is lie is lie 
True
>lie is not lie is lie is lie is lie is lie
False
>lie is lie is lie is lie is lie is not lie
False

Ответ 3

Он будет интерпретироваться как:

lie = 0
if lie is lie and lie is lie:
    ...