canonical file access pattern?

John J. Lee jjl at pobox.com
Wed Dec 31 15:51:01 CET 2003


Hans-Joachim Widmaier <hjwidmaier at web.de> writes:

> Am Tue, 30 Dec 2003 12:00:52 +0100 schrieb Rene Pijlman:
[...]
> > Then this would need to be the algorithm:
> > 
> > try:
> >     f = file("spam.txt", "w")
> > except IOError, e:
> >     # Handle open() error
> >     pass
> > else:
> >     try:
> >         try:
> >             # read/write to the file
> >             pass
> >         except IOError, e:
> >             # Handle read/write errors
> >             pass
> >     finally:
> >         try:
> >             f.close()
> >         except IOError, e:
> >             # Handle close error
> >             pass
> 
> While my first thought was: Why is the finally needed here? The close()
> might just as well be the end of the else-suit. But it slowly dawns on me:
> If there is another exception than IOError in the read/write suite,
> closing of the file wouldn't take place.
> 
> > Not very pretty, but I can't think of a simplification that does not
> > violate one of the assumptions.
> 
> Yes, I would second that. Alas, this means that the wonderful pattern
> 
> for line in file(filename, "r"):
>     process_line(line)
> 
> is unusable for any "production quality" program. ;-(
[...]

If that were true, why did exceptions get invented?  If you don't need
to do something different in all those except: clauses, then don't put
them in.  As you know, the nice thing about exceptions is that you're
allowed to handle them in sensible places, so typical usage is like
this:

def frob(filename):
    f = file(filename, "w")
    try:
        # read/write to the file
    finally:
        f.close()

def blah():
    try:
        frob(filename)
    except IOError, e:
        # try something else, or
        print e.strerror


or, even better:

def blah():
    frob(filename)


Shock, horror, where's the except IOError:, you ask?!  It's in the
calling function, of course.

Also, if you want to catch both OSError and IOError, note that
EnvironmentError is their common base class.


John




More information about the Python-list mailing list