Semantics of file.close()

Hrvoje Niksic hniksic at xemacs.org
Tue Jul 17 23:48:40 CEST 2007


"Evan Klitzke" <evan at yelp.com> writes:

> You should take a look at the man pages for close(2) and write(2) (not
> fclose). Generally you will only get an error in C if you try to close
> a file that isn't open. In Python you don't even have to worry about
> that -- if you close a regular file object more than once no exception
> will be thrown, _unless_ you are using os.close(), which mimics the C
> behavior. If you are out of space, in C you will get an error returned
> by the call to write (even if the data isn't actually flushed to disk
> yet by the kernel). I'm pretty sure Python mimics this behavior, so an
> exception would be called on the write, not on the close operation.

But the writes are buffered, and close causes the buffer to be
flushed.  file.close can throw an exception just like fclose, but it
will still ensure that the file is closed.

> > How do I ensure that the close() methods in my finally clause do
> > not throw an exception?

In the general case, you can't.  Preferably you'd want to make sure
that both files are closed:

try:
  f1 = file(...)
  try:
    f2 = file(...)
    ... do something with f1 and f2 ...
  finally:
    f2.close()
finally:
  f1.close()

Now file.close would be called on both files regardless of where an
exception occurs.  If you use Python 2.5, this would be a good use
case for the "nested" function from the contextlib module, which allow
you to write the above more elegantly:

from __future__ import with_statement
from contextlib import nested

with nested(file(...), file(...)) as (f1, f2):
  ... do something with f1 and f2 ...


Finally, most of this applies to files open for writing, where Python
is forced to flush the cache on close.  If the file is opened for
reading, you can assume that the exception will not be raised (and you
can safely ignore it with `try: f.close() except IOError: pass' if you
want to be sure; after all, you can't lose data when closing a file
open for reading).



More information about the Python-list mailing list