2012-07-04 28 views
2

从这方面:重读文件骑车过一个文件对象时,在Python

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

我不知道我怎么可以实现相同的“功能”,但重读当它到达终点的文件,所以如果文件自第一次迭代以来发生了变化,那么在重新开始另一个循环之前它会被重新加载。 (希望我已经解释清楚了)

提前谢谢! :)

回答

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或使用上下文管理器(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关闭自己StopIteration

+0

是的,我更喜欢最后一种方式,似乎更容易理解! :) 也喜欢Python 3.3版本的代码,很好的提醒我需要更新自己!谢谢!! :) –

+1

'而真'似乎是最可读的。你可以适应它的Python <3.3:'在开放(文件名)行:)产量线' – jfs

+0

@ J.F.Sebastian好主意,谢谢。 – ecatmur

2

喜欢的东西

def cycle_file(f): 
    while True: 
     ln = f.readline() 
     if ln == "": 
      f.seek(0) 
      continue 
     yield ln 

除了它可能是不错的投入为空文件,我将离开你一张支票。

+0

这会在最后产生空字符串,对吗?可能是一个错误或功能。 – DSM

+0

@DSM:我忘记了一个'continue'语句。谢谢。 –

+1

如果文件被替换('tail -f'和'tail -F'),这可能会错过更改 – jfs