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

2024-03-29 09:17:52 发布

您现在位置:Python中文网/ 问答频道 /正文

例如

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

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


Tags: informatclosedefsys资源hiresource
1条回答
网友
1楼 · 发布于 2024-03-29 09:17:52

你不能。如果生成器没有被next编辑,那么主体中的任何try子句都没有被输入。close将在函数开始时抛出GeneratorExit,然后才能设置任何异常处理。你知道吗

您必须更改前提-例如,通过引入一个虚拟的yieldnext预先对生成器执行一次操作:

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.

相关问题 更多 >