混合文件和循环

时间:2009-05-05 19:20:06

标签: python python-2.7 file loops while-loop

我正在编写一个脚本,记录来自另一个程序的错误,并在遇到错误时重新启动它停止的程序。无论出于何种原因,该程序的开发人员认为没有必要在默认情况下将此功能放入其程序中。

无论如何,程序接受一个输入文件,解析它,并创建一个输出文件。输入文件采用特定格式:

UI - 26474845
TI - the title (can be any number of lines)
AB - the abstract (can also be any number of lines)

当程序抛出错误时,它会为您提供跟踪错误所需的参考信息 - 即UI,哪个部分(标题或摘要)以及相对于标题或摘要开头的行号。我想从输入文件中记录有问题的句子,其中包含一个带参考号和文件的函数,找到句子并记录它。我能想到的最好的方法是在文件中向前移动特定次数(即n次,其中n是相对于seciton开头的行号)。这样做的方式似乎是:

i = 1
while i <= lineNumber:
    print original.readline()
    i += 1

我不知道这会如何让我丢失数据,但Python认为会这样,并且ValueError: Mixing iteration and read methods would lose data说。有谁知道如何正确地做到这一点?

4 个答案:

答案 0 :(得分:48)

您获得了ValueError,因为除了for line in original:之外,您的代码可能还有original.readline()。一个简单的解决方案可以解决问题而不会使程序变慢或消耗更多内存正在改变

for line in original:
    ...

while True:
    line = original.readline()
    if not line: break
    ...

答案 1 :(得分:12)

使用forenumerate

示例:

for line_num, line in enumerate(file):
    if line_num < cut_off:
        print line

注意:这假设您已经在清理文件句柄等。

此外,如果您更喜欢更实用的风味,takewhile功能可能会很有用。

答案 2 :(得分:0)

假设您只需要一行,这可能会有所帮助

import itertools

def getline(fobj, line_no):
    "Return a (1-based) line from a file object"
    return itertools.islice(fobj, line_no-1, line_no).next() # 1-based!

>>> print getline(open("/etc/passwd", "r"), 4)
'adm:x:3:4:adm:/var/adm:/bin/false\n'

您可能希望捕获StopIteration错误(如果文件的行数较少)。

答案 3 :(得分:-1)

这是一个没有丑陋while True模式且没有其他模块的版本:

for line in iter(original.readline, ''):
    if …:   # to the beginning of the title or abstract
        for i in range(lineNumber):
            print original.readline(),
        break