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
我对生成器 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