[Tutor] Creating files inside a script

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Sat, 21 Apr 2001 19:54:19 -0700 (PDT)


On Sat, 21 Apr 2001, Sheila King wrote:

> I've been going through docs, and experimenting, and my experiments
> seem to contradict each other from one time to the next. I'll tell you
> one thing, after I post this message, I am definitely going to go take
> a break!

No problem; that happens to me too.  It stopped raining yesterday, and it
was a gorgeous day for a walk...



About the modes that open() can take in: the problem is that open() is a
wrapper around the C function fopen(), which means that it's not quite as
well documented as the rest of the Python functions.

Doing a "man fopen" on my Linux system gives some detail to what all these
modes mean:

###
Documentation for C's fopen():
---
r Open text file for reading.  The stream is positioned at the beginning
of the file.

r+ Open for reading and writing.  The stream is positioned at the
beginning of the file.

w Truncate file to zero length or create text file for writing.  The
stream is positioned at the beginning of the file.

w+ Open for reading and writing.  The file is created if it does not
exist, otherwise it is truncated.  The stream is positioned at the
beginning of the file.

a Open for writing.  The file is created if it does not exist.  The stream
is positioned at the end of the file.

a+ Open for reading and writing.  The file is created if it does not
exist.  The stream is positioned at the end of the file.
###


Whew.  One caveat: Python's append plus "a+" mode behaves differently from
C's "a+" mode.  Here's what the Python reference manual says:

"Modes 'r+', 'w+' and 'a+' open the file for updating... If the file
cannot be opened, IOError is raised."

    http://python.org/doc/current/lib/built-in-funcs.html

We'll talk about this later in this message.



> OK, as far as creating files...let's just assume that I have the name of the
> file I want to work with hard-coded into my script.
> 
> If I do
> 
> f = open(filename, 'w')
> It will create the file, if it does not already exist, otherwise it will
> truncate an existing file, losing all previously existing data.
> 
> How does this compare with
> f = open(filename, 'w+')  ???

In "w+" mode, the file can also be used for reading as well: we're allowed
to do read() calls on it.  All of the "plus" modes allow reading and
writing: the main difference between them is where we're positioned in the
file.  "r+" puts us at the beginning.  "w+" puts us at the beginning and,
technically, the end, because the file's truncated.  "a+" puts us at the
end.



> f = open(filename, 'a')
> and the file already exists, this will simply append new text written to the
> file to the end of the already existing stuff.
> What if the file doesn't already exist? I thought, it would create the file.
> But, it seemed at some points today, as though I was getting IOErrors, for
> being unable to open the file, because it did not already exist, when using an

In C, it would have been ok.  However, the Python docs appear to say that
if the files don't exist, it'll throw off an IOError.  I wonder why they
made the behavior different than from C...  In any case, that's why the
IOErrors are popping up.


In summary, it appears that all '+' modes allow reading and writing.  
However, you're right that this is a little confusing: it FEELS
inconsistant how the Python implementors have done this:

###
## Assume that foo1.txt, foo2.txt, and foo3.txt don't exist in the
## current directory.
>>> open('foo1.txt', 'r+')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IOError: [Errno 2] No such file or directory: 'foo1.txt'
>>> open('foo2.txt', 'a+')
<open file 'foo2.txt', mode 'a+' at 0x80e6c80>
>>> open('foo3.txt', 'w+')
<open file 'foo3.txt', mode 'w+' at 0x80e2798>        
###

*sigh* So the updating append, "a+", appears to be a special case that's
not symmetric: "a+" will assume that the file exists, but if it doesn't,
it raises an IOError.  Perhaps this is a bug though; we should ask one of
the Python implementors why "a+" is a special case.


Now I need to take a break.  *grin*