gpt4 book ai didi

python - Python 中的链式比较实际上是如何工作的?

转载 作者:太空狗 更新时间:2023-10-29 20:51:44 24 4
gpt4 key购买 nike

Python Doc for Comparisons说:

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

这些 SO 问题/答案更清楚地说明了这种用法:

所以像(人为的例子):

if 1 < input("Value:") < 10: print "Is greater than 1 and less than 10"

只要求输入一次。这是有道理的。还有这个:

if 1 < input("Val1:") < 10 < input("Val2:") < 20: print "woo!"

只要求 Val2 如果 Val1介于 1 和 10 之间,只打印“woo!” 如果 Val2也在 10 到 20 之间(证明它们可以“任意链接”)。这也是有道理的。

但我仍然很好奇这是如何在词法分析器/解析器/编译器(或其他)级别实际实现/解释的。

上面第一个例子基本上是这样实现的:

x = input("Value:")
1 < x and x < 10: print "Is between 1 and 10"

哪里x真的只存在(实际上基本上未命名)用于这些比较吗?或者它是否以某种方式使比较运算符返回 bool 结果和正确操作数的评估(用于进一步比较)或类似的东西?

将分析扩展到第二个示例使我相信它使用的是类似于未命名的中间结果(如果有这个术语,请教我),因为它在进行比较之前不会评估所有操作数。

最佳答案

您可以简单地让 Python 告诉您使用 dis module 生成的字节码是什么:

>>> import dis
>>> def f(): return 1 < input("Value:") < 10
...
>>> dis.dis(f)
1 0 LOAD_CONST 1 (1)
3 LOAD_GLOBAL 0 (input)
6 LOAD_CONST 2 ('Value:')
9 CALL_FUNCTION 1
12 DUP_TOP
13 ROT_THREE
14 COMPARE_OP 0 (<)
17 JUMP_IF_FALSE_OR_POP 27
20 LOAD_CONST 3 (10)
23 COMPARE_OP 0 (<)
26 RETURN_VALUE
>> 27 ROT_TWO
28 POP_TOP
29 RETURN_VALUE

Python 使用堆栈; CALL_FUNCTION bytecode使用堆栈上的项(input 全局变量和 'Value:' 字符串)调用带有一个参数的函数,用函数调用的结果替换堆栈上的这两项。在函数调用之前,常量 1被加载到堆栈上。

到时候 input被调用的堆栈看起来像:

input_result
1

DUP_TOP 复制顶部值,在 rotating the top three stack 之前要达到的值:

1
input_result
input_result

和一个COMPARE_OP使用 < 测试前两项, 用结果替换前两项。

如果结果是 False JUMP_IF_FALSE_OR_POP bytecode跳转到 27,旋转 False在顶部与剩余的 input_resultPOP_TOP 清除它, 然后返回剩余的 False最高值作为结果。

如果结果True然而,这个值被JUMP_IF_FALSE_OR_POP弹出堆栈。字节码并在其中放置 10值加载在顶部,我们得到:

10    
input_result

然后进行另一个比较并返回。

总而言之,Python 基本上是这样做的:

stack_1 = stack_2 = input('Value:')
if 1 < stack_1:
result = False
else:
result = stack_2 < 10

stack_*值再次被清除。

然后,堆栈保存未命名的中间结果以进行比较

关于python - Python 中的链式比较实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28754726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com