27

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

无论如何,程序获取一个输入文件,解析它,然后创建一个输出文件。输入文件采用特定格式:

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

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

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

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

4

4 回答 4

50

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

for line in original:
    ...

while True:
    line = original.readline()
    if not line: break
    ...
于 2009-05-05T19:47:25.577 回答
12

使用for枚举.

例子:

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

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

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

于 2009-05-05T19:23:58.580 回答
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 错误(如果文件的行数较少)。

于 2009-05-06T08:02:56.243 回答
-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
于 2018-02-02T08:39:36.427 回答