运行下面的代码
print(print('1') or print('2') and print('3') or print('4'))
将导致:
1
2
4
None
我知道优先级是
not
> and
> or
,所以我预料到了
2
1
4
None
我不明白这个结果。请解释一下。
考虑到运算符的优先级以及 print() 函数的行为方式,我们已经逐步分解了提供的 Python 代码:
print(print('1') or print('2') and print('3') or print('4'))
结果
打印('1')
为 None,因为 print() 始终返回 None。 表达式如下:
None or **print('2')** and **print('3')** or **print('4')**
表达式变为:
None and print('3')
现在我们有:
None or None or print('4')
最终操作:print('4')
最终输出:
1
2
4
None
简短的回答是用户 interjay 来自评论的精彩总结:
优先级决定在哪里添加括号。它不会改变特定运算符的操作数的求值顺序。
长答案:
print()
返回None
并且有“副作用”print()
返回None
(参见这个SO线程),但它的副作用是在标准输出上打印。
>>> a = print('1')
1
>>> print(a)
None
忽略外部打印语句,您的代码
print('1') or print('2') and print('3') or print('4')
成为
None or None and None or None
并将返回
None
运算符优先级仅决定语句应如何“分组”以进行评估,但是“短路”规则与具有“副作用”的函数相结合,似乎会违反规则。
解释上面链接的规则:
仅当第一个参数为 false 时才计算第二个参数。or
仅当第一个参数为 true 时才计算第二个参数。and
因此,考虑到上述优先级和规则,您的代码
print('1') or print('2') and print('3') or print('4')
将成为
print('1') or ( ( print('2') and print('3') ) or print('4') )
----1----- -------------------------------------------
------------2------------
----3-----
但是这些是执行步骤,给出了上面的规则:
print('1')
是 None
,它是“假 y”值,因此给定规则 1,对其进行评估,并且
print('1') or ( ... )
我们继续剩下的:
( print('2') and print('3') ) or (...)
--None---- --None----
必须首先评估
and
语句,并且给定规则 1,对 print('2')
进行评估,但因为即使它打印 2
,它也会返回“假 y”值,所以会跳过 print('3')
。
and
语句返回“false”,因此根据规则1,我们将继续评估or
。
print('4')
已执行。