使用短路运算符时出现意外的求值顺序

问题描述 投票:0回答:2

运行下面的代码

print(print('1') or print('2') and print('3') or print('4'))

将导致:

1
2
4
None

我知道优先级是

not
>
and
>
or
,所以我预料到了

2
1
4
None

我不明白这个结果。请解释一下。

python short-circuiting
2个回答
1
投票

考虑到运算符的优先级以及 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

1
投票

简短的回答是用户 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

代码执行的优先级和顺序

运算符优先级仅决定语句应如何“分组”以进行评估,但是“短路”规则与具有“副作用”的函数相结合,似乎会违反规则。

解释上面链接的规则:

  1. or
    仅当第一个参数为 false 时才计算第二个参数。

  2. and
    仅当第一个参数为 true 时才计算第二个参数。

因此,考虑到上述优先级和规则,您的代码

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-----     

但是这些是执行步骤,给出了上面的规则:

  1. print('1')
    None
    ,它是“假 y”值,因此给定规则 1,对其进行评估,并且

    print('1') or ( ... )
    
  2. 我们继续剩下的:

    ( print('2') and print('3') ) or (...)
      --None----     --None----
    

    必须首先评估

    and
    语句,并且给定规则 1,对
    print('2')
    进行评估,但因为即使它打印
    2
    ,它也会返回“假 y”值,所以会跳过
    print('3')

    and
    语句返回“false”,因此根据规则1,我们将继续评估
    or

  3. print('4')
    已执行。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.