保证sstream
在我们完成迭代后将关闭的最佳方法是foo()
什么?
在绝对必须调用的“清理”函数的一般情况下,您可能必须在生成器之外调用它,例如......
from StringIO import StringIO
def foo(sstream):
for line in sstream:
res = doSomethingWith(line)
yield res
sio = StringIO(mystring)
try:
for bar in foo(sio):
if condition(bar):
break
finally:
sio.close()
上下文管理器似乎不能在生成器内部工作,除非它们已经筋疲力尽。例如...
from StringIO import StringIO
from contextlib import contextmanager
@contextmanager
def my_stringio(s):
print 'creating StringIO'
sio = StringIO(s)
yield sio
print 'calling close()'
sio.close()
def mygen():
with my_stringio('abcdefghij') as sio:
while 1:
char = sio.read(1)
if not char:
break
yield char
for char in mygen():
print char
if char == 'c':
break
...从不打印'calling close()'
。
我是否必须将生成器包装在类定义中并实现
__del__
?
这是另一种选择,但这种方法的问题在于,如果您设法用类实例创建循环引用,则该__del__
方法将永远不会被调用。
或者我可以在这里依靠垃圾收集吗?
在这种情况下,您可以。
使用 a调用该方法StringIO
并不重要。close()
您可能要确保的唯一一件事是它正在使用的内存已被垃圾收集,无论您的for
循环终止的方式如何,这都会发生 - 生成器将超出范围,并且其本地将被 GC'd。