2014-03-04 35 views
12

我注意到一些奇怪的行爲今天next()readline()玩耍。看來,這兩個函數產生相同的結果(這是我所期望的)。然而,當我混合他們,我得到一個ValueError。下面是我所做的:混合file.readline()和file.next()

>>> f = open("text.txt", 'r') 
>>> f.readline() 
'line 0\n' 
>>> f.readline() 
'line 1\n' 
>>> f.readline() 
'line 2\n' 
>>> f.next() 
'line 3\n' 
>>> f.next() 
'line 4\n' 
>>> f.readline() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Mixing iteration and read methods would lose data 
>>> 
>>> f = open("text.txt", 'r') 
>>> f.next() 
'line 0\n' 
>>> f.next() 
'line 1\n' 
>>> f.next() 
'line 2\n' 
>>> f.readline() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Mixing iteration and read methods would lose data 

所以這裏的整體問題是發生了什麼事情導致此錯誤引擎蓋底下?

可能得到與回答一起,但我想聽到的答案,如果沒有一些問題:

  1. 什麼是next()readline()之間的區別是什麼?
  2. 當我做for f in file:哪些功能我在打電話(和它的問題)?
  3. 爲什麼我可以叫next()readline()之後,而不是周圍的其他方式?

由於提前,

,我不認爲它很重要,但如果這取決於版本,我對Python的2.7.6的Windows

回答

19

根據Python's doc(重點是mine)

文件對象是它自己的迭代器,例如iter(f)返回f(除非f關閉)。當一個文件被用作迭代,通常在for循環中(例如,用於在F線:打印line.strip()),的next()方法被反覆調用。此方法返回下一個輸入行,或者在打開文件時打開EOF時引發StopIteration(當文件打開時寫入時行爲未定義)。爲了使循環在文件的行(一個非常常見的操作),下一個()方法使用一個隱藏的預讀緩衝區 for循環的最有效方法。作爲使用預讀緩衝區的結果,將next()與其他文件方法(如readline())組合使用並不正確。但是,使用seek()將文件重新定位到絕對位置將刷新預讀緩衝區。

next方法讀取效率更高的原因。這打破readline。 所以答案是

  1. next更快,因爲其預讀
  2. for s in f:使用next
  3. 調用next之前,readline上使用標準文件讀取速度慢,所以沒有問題。
+1

在Python 3,混合'下一個(F)'和'f.readline()'是允許的,雖然。 –

+0

@SvenMarnach你怎麼知道?請參閱Python文檔。 –

+1

@ patryk.beza你將不得不相信我。 :)我不認爲這是明確記錄。我通過閱讀源代碼瞭解它。Python 3有一個全新的I/O層,'__next __()'或者調用'readline()',或者被實現爲完全相同。 –