Python 运算符优先级 - 和 vs 大于

Posted

技术标签:

【中文标题】Python 运算符优先级 - 和 vs 大于【英文标题】:Python operator precedence - and vs greater than 【发布时间】:2015-07-15 04:06:54 【问题描述】:

我的脚本中有一行代码将这两个运算符链接在一起。从文档参考 BOOLEAN AND 的优先级低于 COMPARISON GREATER THAN。我在这段代码中得到了意想不到的结果:

>>> def test(msg, value):
...     print(msg)
...     return value

>>> test("First", 10) and test("Second", 15) > test("Third", 5)
First
Second
Third
True

我预计第二次或第三次测试会在第一次测试之前发生,因为 > 运算符具有更高的优先级。我在这里做错了什么?

https://docs.python.org/3/reference/expressions.html#operator-precedence

【问题讨论】:

第一个值 10 的布尔解释也是 True。因此,10 and 15 > 5 == 10 and (15 > 5) == 10 and True == True 但是为什么解释器在得到 15 或 5 之前得到了 10?比较不应该在布尔检查之前进行吗? test("First", 10) and test("Second", 15) > test("Third", 5) 等价于 test("First", 10) and (test("Second", 15) > test("Third", 5)) Python 也会计算 and lazily 那么优先级绝对正确。 0 and 0 > -1(0 and 0) > -1 不同。我的猜测是,虽然返回的值以正确的顺序进行评估,但由于某种原因,函数没有按该顺序调用。有趣的是,用 0,0,-1 替换 10,15,5 只会打印 First。也许这是一个编译器优化 - 因为在你的情况下,正如@Alik 指出的那样,两个订单都会产生相同的值。 【参考方案1】:

因为你看错了东西。 call(或函数调用)优先于 and>(大于)。所以第一个函数调用是从左到右发生的。

在比较发生之前,Python 将获得所有函数调用的结果。这里唯一优先的是短路,所以如果test("First",10) 返回 False,它将短路并返回 False。

and 的比较仍然以相同的优先级发生,即首先将test("Second", 15) 的结果与test("Third", 5) 进行比较(请注意仅返回值(之前已经发生过函数调用))。然后test("Second", 15) > test("Third", 5)的结果用于and操作。

来自operator precedence 上的文档-

【讨论】:

这很有意义。谢谢你。所以如果我只用数字替换函数调用,我会得到不同的结果,对吧? 对于数字没有什么可评估的,所以我不确定你的意思是什么? Python 将在比较发生或and 发生之前获取所有函数调用的结果。在这里唯一优先的是短路【参考方案2】:

查看正在发生的事情的一种方法是查看 Python 是如何解释这个结果的:

>>> x = lambda: test("First", 10) and test("Second", 15) > test("Third", 5)
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (test)
              3 LOAD_CONST               1 ('First')
              6 LOAD_CONST               2 (10)
              9 CALL_FUNCTION            2
             12 JUMP_IF_FALSE_OR_POP    42
             15 LOAD_GLOBAL              0 (test)
             18 LOAD_CONST               3 ('Second')
             21 LOAD_CONST               4 (15)
             24 CALL_FUNCTION            2
             27 LOAD_GLOBAL              0 (test)
             30 LOAD_CONST               5 ('Third')
             33 LOAD_CONST               6 (5)
             36 CALL_FUNCTION            2
             39 COMPARE_OP               4 (>)
        >>   42 RETURN_VALUE        

如果你对10 and 15 > 5 做同样的事情,你会得到:

>>> x = lambda: 10 and 15 > 5
>>> dis.dis(x)
  1           0 LOAD_CONST               1 (10)
              3 JUMP_IF_FALSE_OR_POP    15
              6 LOAD_CONST               2 (15)
              9 LOAD_CONST               3 (5)
             12 COMPARE_OP               4 (>)
        >>   15 RETURN_VALUE        

【讨论】:

以上是关于Python 运算符优先级 - 和 vs 大于的主要内容,如果未能解决你的问题,请参考以下文章

运算符的优先级

Python中的运算符与表达式

02-python-运算符与表达式

运算符

python编程基础之七

VB运算符在运算式的顺序是啥?