Python 如何在尚未迭代的生成器中捕获GeneratorExit?

Python 如何在尚未迭代的生成器中捕获GeneratorExit?,python,Python,例如: 在Python中,如果没有进入生成器,是否无法注意到生成器的close()调用 (在我的实际用例中,生成器的一个参数是返回生成器的函数传递给生成器的资源,包括所有权。即 def do_it(): 资源=获取() 尝试: 返回一个_生成器(资源)(#传递资源的所有权 除: resource.close() 如果在第一次迭代之前关闭生成器,而生成器无法捕获该事实,则资源泄漏。)您不能。如果未对生成器执行nexted,则未输入正文中的任何try子句close将在函数开始时抛出Generato

例如:

在Python中,如果没有进入生成器,是否无法注意到生成器的
close()
调用

(在我的实际用例中,生成器的一个参数是返回生成器的函数传递给生成器的资源,包括所有权。即

def do_it():
资源=获取()
尝试:
返回一个_生成器(资源)(#传递资源的所有权
除:
resource.close()

如果在第一次迭代之前关闭生成器,而生成器无法捕获该事实,则资源泄漏。)

您不能。如果未对生成器执行
next
ed,则未输入正文中的任何
try
子句
close
将在函数开始时抛出
GeneratorExit
,然后才能设置任何异常处理

您必须更改前提-例如,通过引入一个虚拟的
yield
next
提前一次启动生成器:

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()

你可以编写一个基于类的生成器并重写close方法。这是我的怀疑。太遗憾了,Python。
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.