Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
443 views
in Technique[技术] by (71.8m points)

python - Mixing file.readline() and file.next()

I noticed some strange behavior today playing around with next() and readline(). It seems that both functions produce the same results (which is what I expect). However, when I mix them, I get a ValueError. Here's what I did:

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

So the overall question here is what's going on underneath the hood that causes this error?

Some questions that might get answered along with but I would like to hear an answer for if not:

  1. What are the differences between next() and readline()?
  2. When I do for f in file: which function am I calling (and does it matter)?
  3. Why can I call next() after readline(), but not the other way around?

Thanks in advance,

I don't think it matters, but in case this is version dependent, I'm on Python 2.7.6 for Windows

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

According to Python's doc (emphasis is mine)

A file object is its own iterator, for example iter(f) returns f (unless f is closed). When a file is used as an iterator, typically in a for loop (for example, for line in f: print line.strip()), the next() method is called repeatedly. This method returns the next input line, or raises StopIteration when EOF is hit when the file is open for reading (behavior is undefined when the file is open for writing). In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation), the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.

The next method reads more that is needed for efficiency reasons. This breaks readline. So the answers are

  1. next is faster due to read-ahead
  2. for s in f: use next
  3. before calling next, readline uses standard slow read on the file so there is no problem.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...