从这个背景来看:
import itertools
lines = itertools.cycle(open('filename'))
我想知道如何实现相同的'功能',但是当文件到达结尾时重新读取文件,所以如果文件在第一次迭代后被更改,则会在开始另一个循环之前重新加载。 (希望我已经解释得很好)
提前谢谢! :)
答案 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
除了检查空文件可能会很好,我会留给你。