函数抛出异常的时候,我们可以获得一个调用栈,得到每一步调用的文件、函数、行号,方便追踪异常的产生原因。当生成器抛出异常的时候,我们怎么来获取它当前执行到具体位置了呢?
每个生成器都有如下三个属性:gi_frame, gi_code, gi_running.gi_code是生成器的代码,根据这个对象我们可以获取到生成器的函数名、文件名。gi_frame相当于栈帧,记录了生成器执行的状态,根据这个对象我们可以获取到执行到的行号信息。
示例代码如下。
def fn():
yield 1
yield 2
print 'after 2'
yield 3
def show(c):
fr = c.gi_frame
code = c.gi_code
filename = code.co_filename
lineno = fr.f_lineno
fn_name = code.co_name
print "run at %s %s():%d" %(filename, fn_name, lineno)
y=fn()
show(y)
for n in y:
show(y)
在上述代码中,我们先定义了一个生成器函数fn(),接着定义查看生成器状态的函数show(),在这个函数里查询gi_frame和gi_code输出文件、函数名、行号等信息。
在第一个show()的调用时,此时生成器还没执行,行号指向fn()定义的行号,接着是循环,生成器不断执行,全部输出如下所示。
run at C:/Users/Administrator/Documents/gen.py fn():1
run at C:/Users/Administrator/Documents/gen.py fn():2
run at C:/Users/Administrator/Documents/gen.py fn():3
after 2
run at C:/Users/Administrator/Documents/gen.py fn():5
以上输出清晰的显示了生成器的执行过程。
网友评论