python 生成器主体中打开手柄的寿命

Lifespan of open handles in a python generator body

我对生成器 and/or python 的执行模型有疑问。

给定如下:

def g(filename):
    with open(filename) as handle:
        for line in handle:
            yield some_trasformation_on(line)

我的主要困惑是:如果

会发生什么处理
res = g()
print(next(res))

只调用一次?句柄是否在程序的整个生命周期内保持打开状态?如果我们在生成器主体中分配了稀缺资源怎么办?线程?数据库句柄?

也许我正在考虑生成器就像引擎盖下的函数。

用所写的代码回答

如上所述,文件将在程序的整个生命周期内保持打开状态。当您引用 res 变量时,它使生成器堆栈框架保持活动状态,因此使用 with 语句关闭文件的唯一方法是继续调用 next() 直到 for 循环正常结束。

如何清理生成器

为清理生成器而设计的工具在生成器内部generator.close() which raises a GeneratorExit

这里有一些工作代码来展示它是如何完成的:

def genfunc(filename):
    try:
        with open(filename) as datafile:
            for line in datafile:
                yield len(line)
    finally:
        print('Status: %s' % datafile.closed)

这是一个示例会话,显示实际发生的关闭操作:

>>> g = genfunc('somefile.txt')
>>> next(g)
23
>>> g.close()
Status: True