我在python解释器中玩弄逻辑表达式,我似乎无法弄清楚python在引擎盖下真正使用的执行过程。我已经看到这个表(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"的输出,然后是零除错误。但是,我引用的网站提到函数调用是第二高的优先级,所以不应该首先执行打印的两个函数调用吗?我知道有短路评估,但这不是只有在您达到 ands、nots 和 ors 的优先级级别后才会启动吗?
2)
True>False or print("hello")
即使这样也只在 python 解释器上输出 True。 为什么它不先做打印的函数调用?
3)
5 is 5 or 1/0
这将输出 True。但是除法不应该比"is"有更高的优先级吗,这个表达式不应该返回一个ZeroDivsionError吗?
有人可以解释我错过了什么以及如何判断 python 将执行逻辑表达式的顺序吗?
有人可以解释我缺少什么以及如何判断 python 将执行逻辑表达式的顺序吗?
优先级会影响解析到树时对"共享"操作数进行分组的方式。在此之后,每个子表达式的特定评估模型接管。
print("this") or True and 1/0 and print("tester")
你会得到一个看起来像这样的树(你可以使用ast
模块获得更详细但精确的版本,astpretty
得到一些可读的东西):
or
print("this")
and
True
and
1/0
print("tester")
然后评估接管(编译为字节码后,但这不会改变操作顺序):
- 评估外部
or
- 它计算第一个
print
,返回一个 falsy 值,因此 - 它评估第一个
and
- 它评估
True
这是真实的 - 因此,它评估第二个
and
- 评估爆炸
1/0
- 评估爆炸
- 它评估
- 它计算第一个
True>False or print("hello")
这解析为
or
>
True
False
print("hello")
or
计算其第一个操作数(> True False)
评估结果为True
or
是一个短路运算符,一旦找到真值并返回该值,它就会停止,因此它永远不会到达print
5 is 5 or 1/0
这解析为
or
is
5
5
/
1
0
评估
or
is
被计算,并返回True
如上所述,
or
是一个短路运算符并返回第一个真值,因此它会立即返回。
我省略了一些位,例如,从技术上讲/
它计算两个操作数然后应用其操作,函数调用评估它们的所有参数然后执行调用本身。
and
和or
之所以脱颖而出,是因为它们在每个操作数的评估之后执行逻辑,而不是在评估了所有操作数之后(它们是懒惰/短路的):and
返回它得到的第一个虚假结果,或者返回它得到的第一个真实结果,可能只评估它们的第一个操作数。
解析器使用优先级顺序来构造解析树。它的含义与评估顺序不同。
以您的第 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
节点的语义规则中。
附言这个答案不是专门针对Python的。
优先级不会影响 python 计算语句的顺序。在5 is 5 or 1/0
中,python首先检查5 is 5
是否为真,如果是,则忽略第二条语句。换句话说,python总是首先计算第一个语句,而不考虑优先级