Ian*_*nSR 4 python generator break
我正在编写一个看起来像"cat"的Python生成器.我的具体用例是"grep like"操作.我希望它能够在满足条件时突破发电机:
summary={}
for fn in cat("filelist.dat"):
for line in cat(fn):
if line.startswith("FOO"):
summary[fn] = line
break
Run Code Online (Sandbox Code Playgroud)
所以当break发生时,我需要cat()生成器完成并关闭文件句柄fn.
我必须读取包含30 GB总数据的100k文件,并且FOO关键字出现在标题区域中,因此在这种情况下,该cat()功能必须尽快停止读取文件.
还有其他方法可以解决这个问题,但我仍然有兴趣知道如何从具有打开文件句柄的生成器中提前退出.也许Python立即清理它们并在生成器被垃圾收集时关闭它们?
谢谢,
伊恩
生成器有一个在语句close中引发的方法.如果您专门捕获此异常,则可以运行一些拆卸代码:GeneratorExityield
import contextlib
with contextlib.closing( cat( fn ) ):
...
Run Code Online (Sandbox Code Playgroud)
然后在cat:
try:
...
except GeneratorExit:
# close the file
Run Code Online (Sandbox Code Playgroud)
如果您想要一种更简单的方法(不使用close生成器上的奥术方法),只需创建cat一个类似文件的对象而不是打开的字符串,并自己处理文件IO:
for filename in filenames:
with open( filename ) as theFile:
for line in cat( theFile ):
...
Run Code Online (Sandbox Code Playgroud)
但是,您基本上不需要担心这一点,因为垃圾收集将处理所有这些.仍然,
显性比隐含更好
通过在同一个对象中实现上下文协议和迭代器协议,您可以编写非常甜蜜的代码,如下所示:
with cat("/etc/passwd") as lines:
for line in lines:
if "mail" in line:
print line.strip()
break
Run Code Online (Sandbox Code Playgroud)
这是一个示例实现,在Linux机器上使用Python 2.5进行了测试.它会读取/etc/passwd直到找到用户的行audio,然后停止:
from __future__ import with_statement
class cat(object):
def __init__(self, fname):
self.fname = fname
def __enter__(self):
print "[Opening file %s]" % (self.fname,)
self.file_obj = open(self.fname, "rt")
return self
def __exit__(self, *exc_info):
print "[Closing file %s]" % (self.fname,)
self.file_obj.close()
def __iter__(self):
return self
def next(self):
line = self.file_obj.next().strip()
print "[Read: %s]" % (line,)
return line
def main():
with cat("/etc/passwd") as lines:
for line in lines:
if "mail" in line:
print line.strip()
break
if __name__ == "__main__":
import sys
sys.exit(main())
Run Code Online (Sandbox Code Playgroud)
甚至更简单:
with open("/etc/passwd", "rt") as f:
for line in f:
if "mail" in line:
break
Run Code Online (Sandbox Code Playgroud)
文件对象实现迭代器协议(请参阅http://docs.python.org/library/stdtypes.html#file-objects)
| 归档时间: |
|
| 查看次数: |
6294 次 |
| 最近记录: |