Will file be closed automatically in a "for ... in open..." statement?

Cameron Simpson cs at zip.com.au
Tue Feb 16 04:24:05 EST 2016


On 16Feb2016 00:39, jfong at ms4.hinet.net <jfong at ms4.hinet.net> wrote:
>I know
>
>    with open('foo.txt') as f:
>        ...do something...
>
>will close the file automatically when the "with" block ends.

Yes, because open is a context manager - they're great for reliably tidying up 
in the face of exceptions or "direct" departure from the block, such as a 
"return" statement.

>I also saw codes in a book:
>
>    for line in open('foo.txt'):
>	...do something...
>
>but it didn't mention if the file will be closed automatically or not when the 
>"for" block ends. Is there any document talking about this? and how to know if 
>a file is in "open" or not?

This does not reliably close the file.

In CPython (the common implementation, and likely what you are using), objects 
are reference counted and when the interpreter notices their counter go to 
zero, the object's __del__ method is called before releasing the object's 
memory.

For an open file, __del__ _does_ call close if the file is open. However, only 
reference counting Pythons will call __del__ promptly - other systems rely on 
garbage collectors to detect unused objects.

In the for loop above, for interpreter obtains an iterator from the open file 
which returns lines of text. That iterator has a reference to the open file, 
and the for loop has a reference to the iterator. Therefore the file remains 
references while the loop runs. AT the end of the loop the iterator is 
discarded, reducing its references to zero. That in turn triggers releasing the 
open file, dropping its references to zero.

In CPython, that in turn will fire the open file's __del__, which will close 
the file. In other Pythons, not necessarily that promptly.

Also, there are plenty of ways to phrase this where the file reference doesn't 
go to zero. FOr example:

  f = open(...)
  for line in f:
    ...

You can see that it is easy to forget to close the file here (especially if you 
have an exception or exit the function precipitously).

Try to use the "with open(...) as f:" formulation when possible. It is much 
better.

Cheers,
Cameron Simpson <cs at zip.com.au>


More information about the Python-list mailing list