filehandle.tell()函数的奇怪行为

时间:2011-12-01 21:52:28

标签: python

我不明白为什么tell()函数在这种情况下不起作用。让我们在里面创建一个字符串为“1 \ n2 \ n3 \ n4 \ n”的文件:

f=open('test.tmp','w')
f.write('1\n2\n3\n4\n')
f.close()

现在,让我们打开它并运行以下代码:

fTellResults=[]
f=open('test.tmp','r+')
for line in f:
    fTellResults.append(f.tell())
f.close()
print fTellResults

结果我得到了:

[8L, 8L, 8L, 8L]

然而,我更期待这一点:

[2L, 4L, 6L, 8L]

有人能解释一下为什么它会这样工作,我怎么能得到预期的结果呢?

P.S。我在Linux上使用Python 2.7.1

2 个答案:

答案 0 :(得分:3)

  

file.next()

     

文件对象是它自己的迭代器,例如iter(f)返回 f (除非 f 关闭)。当文件用作迭代器时,通常在for循环中(例如,for line in f: print line),重复调用next()方法。此方法返回下一个输入行,或者当文件打开以供读取时触发EOF时引发StopIteration(当文件打开以进行写入时,行为未定义)。为了使for循环成为循环文件行的最有效方式(一种非常常见的操作),next()方法使用隐藏的预读缓冲区。使用预读缓冲区的结果是,将next()与其他文件方法(如readline())组合不起作用。但是,使用seek()将文件重新定位到绝对位置将刷新预读缓冲区。

基于此,我声称file.tell给出的位置不正确,因为该文件已被读取到预读缓冲区。

答案 1 :(得分:1)

问题是for line in f:导致在执行循环之前读取所有行。那么在循环的每次迭代中,tell()只在文件末尾保持不变。对于所需的行为,您需要在循环中执行readline