对 Python 中的运算符优先级感到困惑

Confused about Operator Precedence in Python

我在 python 解释器中摆弄逻辑表达式,我似乎无法弄清楚 python 背后真正使用的是什么执行过程。我已经看到 table (http://www.mathcs.emory.edu/~valerie/courses/fall10/155/resources/op_precedence.html) 描述了 python 使用的运算符优先级。

1)

print("this") or True and 1/0 and print("tester")

当我将其输入 python 解释器时,我得到 "this" 的输出,然后是零除法错误。但是,我引用的站点提到函数调用是第二高的优先级,所以不应该首先执行 print 的两个函数调用吗?我知道有短路评估,但只有当您达到 and、nots 和 ors 的优先级时,它才会起作用吗?

2)

True>False or print("hello")

即使这样在 python 解释器上也只输出 True。为什么它不先调用 print 函数呢?

3)

5 is 5 or 1/0

这会输出 True。但是除法不应该比 "is" 具有更高的优先级并且这个表达式 return 不应该是 ZeroDivsionError 吗?

谁能解释一下我遗漏了什么以及如何判断 python 将以什么顺序执行逻辑表达式?

优先级不影响 python 计算语句的顺序。在5 is 5 or 1/0中,python首先检查5 is 5是否为真,如果是,则忽略第二条语句。换句话说 python 总是首先计算第一个语句,不管优先级

解析器使用优先顺序来构造解析树。与评价顺序的含义不同

以您的第3个案例为例:5 is 5 or 1/0。优先顺序为 / > is > or.

解析树看起来像这样(根据优先级。)

     or
   /    \
  is    div
 / \    / \
5   5  1   0

根据提供给代码生成器的另一条规则,评估(从技术上讲,代码生成)从顶部开始,在本例中为 or 节点。 or 的代码生成器的输出可能看起来像这样。

t = code(5 is 5)
if t goto L1
L2: code(1/0)
    goto L1
L1:

优先顺序最初仅用于创建解析树。解析树构建完成后,语义规则(动作?我忘了单词)开始发挥作用。

短路行为内置于 or 节点的语义规则中。

p.s。此答案不适用于 Python。

Can someone explain what I'm missing and how to tell in what order python will execute a logical expression?

优先级会影响 "shared" 操作数在解析为树时的分组方式。之后,每个 sub-expression 的特定评估模型接管。

print("this") or True and 1/0 and print("tester")

你得到一棵看起来像这样的树(你可以使用 ast 模块获得更详细但更准确的版本,并且 astpretty 获得可读的东西):

    or
        print("this")
        and
             True
             and
                 1/0
                 print("tester")

然后 评估接管(在编译为字节码之后但不会改变操作顺序):

  1. 外部or被评估
    1. 它评估第一个 print,returns 一个虚假值,因此
    2. 它评估第一个 and
      1. 它评估 True 是真实的
      2. 因此它计算第二个 and
        1. 哪个评价1/0哪个爆炸

True>False or print("hello")

这解析为

or
   >
      True
      False
   print("hello")
  1. or 计算其第一个操作数

    1. (> True False) 的计算结果为 True

    or 是一个 short-circuiting 运算符,它会在找到真值和 returns 后立即停止,因此它永远不会到达 print

5 is 5 or 1/0

这解析为

or
    is
        5
        5
    /
        1
        0
  1. or评价

    1. is被计算,returnsTrue

    如上,or是一个short-circuiting运算符,returns是第一个真值,所以它立即returns。

我遗漏了一些位,例如从技术上讲,/ 评估两个操作数然后应用其操作,函数调用评估它们的所有参数 然后 执行调用本身。

andor 脱颖而出,因为它们在每个操作数求值后执行逻辑,而不是在对所有操作数求值后执行逻辑(它们很懒惰 / short-circuiting):and returns 它得到的第一个假结果,或者 returns 它得到的第一个真结果,可能只评估它们的第一个操作数。