如何在Python中取消已读取的一行

8

我刚接触Python(2.6),现在遇到这样的情况:我需要取消刚读取文件中的一行。以下是我大致的操作:

  for line in file:
     print line
     file.seek(-len(line),1)
     zz = file.readline()
     print zz

然而,我注意到“zz”和“line”不同。我错在哪里了?谢谢。

5
如果您“取消阅读”一行文本,您会得到什么好处? - quamrana
@quamrana:有点难以解释。那就是我正在操作的代码是这样编写的 :) - user721975
3
以下是翻译的结果: 这里有一个例子(我现在所使用的):你正在从文件中读取一块数据,但是没有明确的块结尾标记,不过你可以识别出何时到达了下一块。在这种情况下,你不希望处理第 i 块的过程消耗掉第 i+1 块的开头,因此“取消读取”非常有意义。 - Eric Anderson
4个回答

12

我认为循环读取文件和使用 seek 并不搭配。你可以尝试使用如下代码:

while True:
    line = file.readline()
    print line
    file.seek(-len(line),1)
    zz = file.readline()
    print zz

    # Make sure this loop ends somehow

我刚刚通过艰难的方式发现了这一点。我来自Perl背景,仍在调整Python。感谢您的答案,它起作用了。 - user721975
3
.readline()在文件结束时返回空字符串'',因此退出条件为if not line: break - jfs

3

您不能将迭代器和seek()方法混合使用。您应该选择一种方法并坚持使用。


2
您可以将对每行的迭代与.seek()操作结合使用:
for i, line in enumerate(iter(f.readline, ''), 1):
    print i, line,
    if i == 2: # read 2nd line two times
       f.seek(-len(line), os.SEEK_CUR)

如果一个文件包含:
a
b
c

那么输出结果将是:
1 a
2 b
3 b
4 c

2

未经测试。基本上,您需要维护一个LIFO缓存的“未读”行。每次读取一行时,如果缓存中有内容,首先从缓存中取出它。如果缓存中没有内容,则从文件中读取新行。这很简单,但应该能让您开始。

lineCache = []

def pushLine(line):
    lineCache.append(line)

def nextLine(f):
    while True:
        if lineCache:
            yield lineCache.pop(0)
        line = f.readline()
        if not line:
            break
        yield line
    return

f = open('myfile')

for line in nextLine(f):
    # if we need to 'unread' the line, call pushLine on it.  The next call to nextLine will
    # return the that same 'unread' line.
    if some_condition_that_warrants_unreading_a_line:
        pushLine(line)
        continue
    # handle line that was read.

http://code.activestate.com/recipes/502304-iterator-wrapper-allowing-pushback-and-nonzero-tes/ - tzot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接