最近我对以下伪造的python代码的第2行发生了什么感到好奇:
def my_fun(foo,bar):
foo
return foo + bar
我感兴趣的原因是我正在尝试使用Light Table并尝试将手表放在“foo”上。它似乎导致python解释器挂起。
我认为这条线完全没有效果并且不会导致任何错误吗?有人可以解释一下口译员在这里做了什么吗?
答案 0 :(得分:27)
可以通过内置dis模块的帮助来了解正在发生的事情:
import dis
def my_fun(foo,bar):
foo
return foo + bar
dis.dis(my_fun)
dis.dis
函数反汇编函数(是的,它可以自行反汇编),方法和类。
dis.dis(my_fun)
的输出是:
4 0 LOAD_FAST 0 (foo)
3 POP_TOP
5 4 LOAD_FAST 0 (foo)
7 LOAD_FAST 1 (bar)
10 BINARY_ADD
11 RETURN_VALUE
前两个字节码正是我们所需要的:foo
行。
以下是这些字节码的作用:
答案 1 :(得分:9)
什么都没发生。它等同于无意义的操作
查看dis
输出
In [3]: dis.dis(my_fun)
2 0 LOAD_FAST 0 (foo)
3 POP_TOP
3 4 LOAD_FAST 0 (foo)
7 LOAD_FAST 1 (bar)
10 BINARY_ADD
11 RETURN_VALUE
我们可以看到它为foo
快速加载,然后对它做任何事情。
答案 2 :(得分:4)
在命令行中尝试:它只返回foo
中的值。
这并不意味着它在某些特殊情况下不会产生副作用:如果您执行以下操作:
def my_fun(foo, bar):
foo.prop
return foo.func(bar)
即使技术上我们刚刚返回了值,如果它被定义为属性,那么foo.prop
实际上可以调用一个函数。
但通常......你不会在模块中这样做,只能在交互式控制台中这样做。
答案 3 :(得分:2)
foo
语句是expression statement的示例,因此在解释器遇到它时会对其进行评估。
表达式语句计算表达式列表(可能是 单表达。)
所以加载了foo
,表达式被评估(它本身是foo
,因此不需要进一步的操作)并且结果立即被遗忘。
答案 4 :(得分:1)
什么都没发生:
>>> def baz(foo, bar):
foo
return bar
>>> baz(10, 20)
20
声明无效。