2

I was playing around in the interpreter and the file.write() method was acting weird, I'm hoping someone can explain it.

>>> file.seek(0)
>>> file.tell()
0
>>> file.readline()
'The Project Gutenberg EBook of The Adventures of Sherlock Holmes\n'
>>> file.tell()
65
>>> file.realine()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'file' object has no attribute 'realine'
>>> file.readline()
'by Sir Arthur Conan Doyle\n'
>>> file.tell()
91
>>> file.write("line\n")
>>> file.tell()
4101
>>> 

Why did file.write("line\n") make it jump to 4101?

file is a copy of this: http://norvig.com/big.txt opened in r+ mode

Thirdegree
  • 21
  • 2

2 Answers2

6

Some implementations of Python use a read-ahead buffer for readline. So after calling readline the position of the filehandle is not necessarily at the end of the line just read.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
2

It's not just buffers at work here: if you're going to mix reading and writing a file, you must do a file-positioning operation (like seek()) between switching from reading to writing, or from writing to reading. "must" means the behavior is undefined otherwise - it may or may not appear to work on any given platform, and on a single platform may appear to work in some cases but not in others. Here's a link to an answer I gave in 2005 (LOL! it's an old problem), which contains references to the C standard (much of Python's file I/O behavior is inherited from the platform C libraries):

https://mail.python.org/pipermail/python-bugs-list/2005-August/029886.html

Tim Peters
  • 67,464
  • 13
  • 126
  • 132
  • Beautiful, thank you. I was having a similar problem using for line in file:, had a feeling I might end up doing this. Thanks for the confirmation. – Thirdegree Sep 12 '13 at 19:33