Used to 'file = open(...)', now what?

Alex Martelli aleax at aleax.it
Mon May 12 03:53:12 EDT 2003


<posted & mailed>

Grzegorz Adam Hankiewicz wrote:

> On 2003-05-07, John Hunter <jdhunter at ace.bsd.uchicago.edu> wrote:
>>   for line in file('somefile.dat'):
>>       print line
> 
> Does this mean that the generator closes the file automatically
> when it reaches the end?

That's implementation-dependent, and it's not specifically related
to generators (nor more generally to iterators) vs other constructs.

In Classic Python (i.e. surely up to Python 2.3, and possibly, who
knows, maybe even in the future) an object is automatically deleted
as soon as the number of references to that object falls to zero
(there are also more advanced mechanisms to ensure eventual deletion
of objects that become unreachable without their reference counts
falling to zero, due to "reference loops", but they don't matter in
this specific context).

When a file object is deleted, it closes itself if you hadn't
previously closed it explicitly.

HOWEVER, these are IMPLEMENTATION details, connected to a specific
version and release number of a Python interpreter, and *NOT* part
of the Python language.  Other Python implementations (such as
Jython, or e.g. future parrot-based, dotnet-based, &c, ones) may
rely on faster, more advanced GC mechanisms that do *NOT* give any
guarantee about the timing of finalization for objects that are
"just abandoned".  To ensure that a program will keep running
correctly on any valid implementation of the Python language, you
should finalize explicitly those objects that need finalization
(file objects being a major example).  Otherwise, depending on
implementation details, your files MIGHT not be closed promptly.

The try/finally statement exists to let you do such explicit
finalization in a clear and unambiguoud manner.  E.g.:

    fileiter = file('somefile.txt')
    try:
        for line in fileiter:
            print line
    finally:
        fileiter.close()

Take care -- it's a natural but ERRONEOUS impulse to put the
initialization part (the binding of fileiter) inside the try;
it needs to go BEFORE the try clause, since the finally clause
needs to be executed only if the file WAS successfully opened.


Alex





More information about the Python-list mailing list