On 16Feb2016 00:39, jf...@ms4.hinet.net <jf...@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 <c...@zip.com.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to