为什么 `(2 == 2) == True` 等于 `True` 而 `2 == 2 == True` 等于 `False`?

mrz*_*rzo -3 python

我的问题是这两个陈述:

> 2 == 2 == True
False
> (2 == 2) == True
True
Run Code Online (Sandbox Code Playgroud)

我很困惑。我希望两个表达式相同,因为 Python 会从左到右计算表达式,因此:

> 2 == 2 == True
False
> (2 == 2) == True
True
Run Code Online (Sandbox Code Playgroud)

# (2 == 2) == True
#  |    |
#  ------
#    |
#   True   == True
Run Code Online (Sandbox Code Playgroud)

即使我改变顺序(如果 Python 从右到左计算),我也会得到同样令人困惑的结果:

> True == 2 == 2
False
> True == (2 == 2)
True
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

che*_*ner 5

比较链接。 2 == 2 == True被评估为2 == 2 and 2 == True,第二个比较显然是错误的。(2可能是真的,但事实并非如此True。)

\n

您可以使用该ast模块查看每个表达式生成的不同抽象语法树 (AST)。

\n
>>> print(ast.dump(ast.parse("2 == 2 == True").body[0], indent=2))\nExpr(\n  value=Compare(\n    left=Constant(value=2),\n    ops=[\n      Eq(),\n      Eq()],\n    comparators=[\n      Constant(value=2),\n      Constant(value=True)]))\n\n>>> print(ast.dump(ast.parse("(2 == 2) == True").body[0], indent=2))\nExpr(\n  value=Compare(\n    left=Compare(\n      left=Constant(value=2),\n      ops=[\n        Eq()],\n      comparators=[\n        Constant(value=2)]),\n    ops=[\n      Eq()],\n    comparators=[\n      Constant(value=True)]))\n
Run Code Online (Sandbox Code Playgroud)\n
\n

单独查看 AST 并不能明显看出它A op1 B op2 C相当于A op1 B and B op2 C(您可以看到有一个带有 Compare两个运算符和两个“比较器”的表达式,而不是Compare带有一个运算符和另一个Compare表达式作为一个操作数的表达式。 )为此,您需要文档:

\n
\n

形式上,如果abc、 \xe2\x80\xa6, y,z是表达式,并且op1op2、 \xe2\x80\xa6,opN是比较运算符,则a op1 b op2 c ... y opN z等价于a op1 b and b op2 c and ... y opN z,只不过每个表达式最多计算一次。

\n
\n

AST 提供信息,代码生成器提供该信息的语义。

\n
>>> import dis\n>>> dis.dis(\'2==2==True\')\n  1           0 LOAD_CONST               0 (2)\n              2 LOAD_CONST               0 (2)\n              4 DUP_TOP\n              6 ROT_THREE\n              8 COMPARE_OP               2 (==)\n             10 JUMP_IF_FALSE_OR_POP    18\n             12 LOAD_CONST               1 (True)\n             14 COMPARE_OP               2 (==)\n             16 RETURN_VALUE\n        >>   18 ROT_TWO\n             20 POP_TOP\n             22 RETURN_VALUE\n>>> dis.dis(\'(2==2)==True\')\n  1           0 LOAD_CONST               0 (2)\n              2 LOAD_CONST               0 (2)\n              4 COMPARE_OP               2 (==)\n              6 LOAD_CONST               1 (True)\n              8 COMPARE_OP               2 (==)\n             10 RETURN_VALUE\n
Run Code Online (Sandbox Code Playgroud)\n