如,
In [33]: def gener():
...: try:
...: print('hi')
...: yield 1
...: print('hi 2')
...: yield 2
...: except:
...: print('Closed: {!r}'.format(sys.exc_info()[1]))
...:
In [34]: gener().close()
# ↑ No output!
In [35]: g = gener()
In [36]: next(g)
hi
Out[36]: 1
In [37]: g.close()
Closed: GeneratorExit()
如果您没有使用Python进入生成器,是否无法注意到生成器的close()
调用?
(在我的实际用例中,生成器的一个参数是返回生成器的函数传递给生成器的资源,包括所有权。即,
def do_it():
resource = acquire()
try:
return a_generator(resource)() # pass ownership of the resource
except:
resource.close()
如果在第一次迭代之前关闭生成器,并且生成器无法捕获该事实,那么资源就会泄漏。)
答案 0 :(得分:2)
你做不到。如果生成器未被next
编辑,则尚未输入正文内的任何try
子句。 close
会在函数开头抛出GeneratorExit
,然后才能设置任何异常处理。
您必须更改前提 - 例如,提前一次引入虚拟yield
和next
生成器:
def gen_wrapper():
gen_iter = _gen()
next(gen_iter)
return gen_iter
def _gen():
try:
yield
...
finally:
perform_cleanup()
# Generator returned from gen_wrapper will perform cleanup even if closed immediately.