Python Doc for Comparisons上写着:
Comparisons can be chained arbitrarily, e.g.,
x < y <= z
is equivalent tox < y and y <= z
, except thaty
is evaluated only once (but in both casesz
is not evaluated at all whenx < y
is found to be false).
这些问题/答案让我们对这种用法有了更多的了解:
比如(人为的例子):
if 1 < input("Value:") < 10: print "Is greater than 1 and less than 10"
只要求输入一次。这是有道理的。还有这个:
^{pr2}$如果Val1
在1&10之间,只要求Val2
,并且只打印“woo!”如果Val2
也在10到20之间(证明它们可以“任意链接”)。这也有道理。在
但我仍然很好奇这是如何在lexer/parser/compiler(或其他)级别实现/解释的。在
上面的第一个例子基本上是这样实现的:
x = input("Value:")
1 < x and x < 10: print "Is between 1 and 10"
其中x
真的只存在于这些比较中(实际上是未命名的)?或者它会使比较运算符返回布尔结果和右操作数的求值(用于进一步比较)或类似的东西?在
将分析扩展到第二个例子使我相信它使用了类似于未命名的中间结果(如果有术语的话,有人会告诉我),因为它在进行比较之前没有计算所有的操作数。在
您可以简单地让Python告诉您使用^{} module 生成的字节码:
Python使用堆栈,^{} bytecode 使用堆栈上的项(}字符串)用一个参数调用函数,用函数调用的结果替换堆栈上的这两个项。在函数调用之前,常量
input
全局和{1
被加载到堆栈中。在所以在调用
^{pr2}$input
时,堆栈看起来像:并且^{} 复制顶部值,在rotating the top three stack值之前到达:
和一个
COMPARE_OP
来用<
测试前两个项目,用结果替换前两个项目。在如果结果是} bytecode 跳到27,它将顶部的
False
,则^{False
与剩余的input_result
一起旋转,用POP_TOP
清除掉,然后返回剩余的False
顶部值作为结果。在但是,如果结果
True
,则该值由JUMP_IF_FALSE_OR_POP
字节码弹出堆栈,并在其所在位置将10
值加载到顶部,我们得到:然后进行另一个比较并返回。在
总之,Python基本上是这样做的:
再次清除
stack_*
值。在然后,堆栈将保存未命名的中间结果进行比较
相关问题 更多 >
编程相关推荐