python yield 和finally 相关的一个问题

请问下面两种方式的代码,输出结果顺序为什么不一样?
code1输出为:
end
65
而code2输出为:
65
end

code 1:

def af():
    a=65
    try:
       yield a

    finally:
        print('end')

print(af().next())

code 2:

def af():
    a=65
    try:
       yield a

    finally:
        print('end')

g=af()
print(g.next())
阅读 4.6k
3 个回答

说说我的理解。
如果不实例化一个生成器,直接调用af().__next__方法后,生成器会被“关闭”,“关闭”前会执行finally。
实例化生成器g,调用g.__next__()方法后,g并不会“关闭”,自然也就暂时不会执行finally,直到stopiteration或主程序结束才执行finally。

PEP 342: finally 一定会被执行,无论生成器是否执行结束,finally实际是被garbage collection执行的。所以你直接af().next()时,af()是个临时对象,会在print调用之前先被gc回收,自然先出现end,而g.next()则是正常的方式,g在主程序结束前始终存在,所以end出现在程序运行结束之后,即python在主程序运行结束后运行gc才会执行finally里面的内容

finally里的内容会在析构时执行,所以af先出现end

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题