我正在使用pdb来调试程序。我先后点击'c'来运行代码,每一步pdb都显示我执行了哪一行。
假设我们有这段代码:
def foo(bar):
print(bar)
foo('hey')
首先,第4行调用函数foo。然后pdb显示了行
def foo(bar)
已执行。
为什么呢?这条线不仅仅是一种标签吗?执行“print(bar)”之前会发生什么? (伴随着另一个人的命中)
编辑:我试验过一些事情就是要实际检查定义。事实上,在foo是一个生成器(不能以这种方式调用)的情况下,python仍然会到达那里,然后决定将其视为生成器(或根据情况而定的函数)。
答案 0 :(得分:8)
def
不是Python中的声明,它是一个可执行语句。在运行时,它检索为函数编译的代码对象,将其包装在动态创建的函数对象中,并将结果绑定到def
之后的名称。例如,考虑这个无用的代码:
import dis
def f():
def g():
return 1
dis.dis(f)
这是输出的一部分(这里是Python 2.7.5):
0 LOAD_CONST 1 (<code object g at 02852338, file ...>)
3 MAKE_FUNCTION 0
6 STORE_FAST 0 (g)
这一切通常都是一个看不见的细节,但你可以用它来玩一些模糊的技巧;-)例如,想想这段代码的作用:
fs = []
for i in range(3):
def f(arg=i**3):
return arg
fs.append(f)
print [f() for f in fs]
这是输出:
[0, 1, 8]
这是因为可执行文件def
创建了三个不同的函数对象,每次循环一次。非常有趣: - )
答案 1 :(得分:1)
执行“print(bar)”之前会发生什么?
这只是一个有根据的猜测:我想当前的IP被推入堆栈然后是参数。然后创建一个新的堆栈帧,从堆栈中弹出参数并将其作为本地添加到当前作用域。沿着这条路线的东西。