canonical file access pattern?

Hans-Joachim Widmaier hjwidmaier at web.de
Wed Dec 31 04:36:29 EST 2003


Am Tue, 30 Dec 2003 12:00:52 +0100 schrieb Rene Pijlman:

> The documentation says only IOError can be raised. Is there a bug?
> 
> "When a file operation fails for an I/O-related reason, the exception
> IOError is raised."

Apart from the "usual suspects" like file does not exist or is write
protected, errors aren't that common, so you don't see them all the time.
Maybe my memory is failing, but I have this distinct recollection that I
once used a 'except IOError' and got a OSError, much to my surprise. But
then, this has been quite a while ago. Python was much younger
then, I was still a fledgling Pythonist, and maybe I attributed the
error to the wrong operation ...

> This is not correct, since the file is not closed when an exception is
> thrown by read or write.

Oh, sorry. I silently assumed this to be done in the exception handling
suite. Really should have made that explicit.

> If we assume the following:
> 1. A file that is opened should be closed in all cases 2. Every
> exception raised by read, write or close should be caught and handled
> 
> 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. ;-(
It certainly is ok for throw-away one-liners and (what I do often!)
interactive file converters.

Thanks for elaborating.

Hans-Joachim Widmaier




More information about the Python-list mailing list