在Python中循环文件对象时重新读取文件

时间:2012-07-04 15:46:25

标签: python

从这个背景来看:

import itertools
lines = itertools.cycle(open('filename'))

我想知道如何实现相同的'功能',但是当文件到达结尾时重新读取文件,所以如果文件在第一次迭代后被更改,则会在开始另一个循环之前重新加载。 (希望我已经解释得很好)

提前谢谢! :)

2 个答案:

答案 0 :(得分:3)

我会用:

itertools.chain.from_iterable(itertools.starmap(open, itertools.repeat(("filename",))))

或:

itertools.chain.from_iterable(itertools.starmap(lambda: open("filename"), itertools.repeat(())))

你也可以写一个生成器理解(我想我最喜欢!):

(line for _ in itertools.repeat(()) for line in open("filename"))

这是命令式(基于语句)的等价物:

def cycle_file(filename):
    while True:
        for line in open(filename):
            yield line

或者,使用Python 3.3(使用PEP 380子生成器委派):

def cycle_file(filename):
    while True:
        yield from open(filename)

所有这些问题的一个问题是(在GC平台上,例如Jython),文件将被关闭,直到文件对象被GCed,这可能会在一段时间后发生。要防止打开文件泄漏,您必须在其上调用close或使用contextmanager(with语句)。这自然是以命令式形式出现的:

def cycle_file(filename):
    while True:
        with open(filename) as f:
            for line in f:
                yield line

def cycle_file(filename):
    while True:
        with open(filename) as f:
            yield from f

尝试使用生成器理解来关闭文件变得非常人为:

(line for f in (itertools.chain(f, (f for f in (f,) if f.close() and False))
                for f in (open("filename") for _ in itertools.repeat(())))
 for line in f)

如果Python有一种方法可以指定open ed文件在到达文件末尾时自动关闭,或者告诉contextmanager-iterator在{{ 1}}。

答案 1 :(得分:2)

这样的东西
def cycle_file(f):
    while True:
        ln = f.readline()
        if ln == "":
            f.seek(0)
            continue
        yield ln

除了检查空文件可能会很好,我会留给你。