如何打开带有打开文件句柄的Python生成器

我正在编写一个看起来像“cat”的 Python生成器.我的具体用例是“grep like”操作.我希望它能够在满足条件时突破发电机:

summary={}
for fn in cat("filelist.dat"):
    for line in cat(fn):
        if line.startswith("FOO"):
            summary[fn] = line
            break

所以当发生中断时,我需要cat()生成器来完成并关闭fn的文件句柄.

我必须读取包含30 GB总数据的100k文件,并且FOO关键字出现在标题区域中,因此在这种情况下,cat()函数会尽快停止读取文件.

还有其他方法可以解决这个问题,但我仍然有兴趣知道如何从具有打开文件句柄的生成器中提前退出.也许Python立即清理它们并在生成器被垃圾收集时关闭它们?

谢谢,

伊恩

通过在同一个对象中实现 context protocoliterator protocol,您可以编写非常甜蜜的代码,如下所示:

with cat("/etc/passwd") as lines:
    for line in lines:
        if "mail" in line:
            print line.strip()
            break

这是一个示例实现,在Linux机器上使用Python 2.5进行了测试.它读取/ etc / passwd的行,直到找到用户音频的行,然后停止:

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

甚至更简单:

with open("/etc/passwd", "rt") as f:
    for line in f:
        if "mail" in line:
            break

文件对象实现迭代器协议(参见http://docs.python.org/library/stdtypes.html#file-objects)

相关文章
相关标签/搜索