views:

108

answers:

4

I was under the impression that file objects are immediately closed when their reference counts hit 0, hence the line:

foo = open('foo').read()

would get you the file's contents and immediately close the file. However, after reading the answer to http://stackoverflow.com/questions/1832528/is-close-necessary-when-using-iterator-on-a-python-file-object I get the impression that this does not happen, and that calling .close() on a file object is always necessary.

Does the line above do what I think it's doing and even if it does, is it the Pythonic thing to do?

+4  A: 

If you want to be sure, I'd write the code like this:

from __future__ import with_statement

with open('foo') as f:
    foo = f.read()

That way, your file closes as expected, even with exceptions.

hughdbrown
I understand that, but I'm specifically asking if the code does what I think it does or not. If not, what does it do, if so, is it the right way?
Brent Newey
As @Edward Loper and @tomekszpakowicz say, what happens will depend on the implementation, so whether the "code does what I think it does or not" will depend on where it is running. The solution I am providing is independent of the implementation.
hughdbrown
A: 

No, Python optimize deleting unused objects so It may never close your file (OK at the end of your script at exit it will cleanup). @ hughdbrown have pointed out nice solution.

przemo_li
+3  A: 

The answer is in the link you provided.

Garbage collector will close file when it destroys file object, but:

  • you don't really have control over when it happens.

    While CPython uses reference counting to deterministically release resources (so you can predict when object will be destroyed) other versions don't have to. For example both Jython or IronPython use JVM and .NET garbage collector which release (and finalize) objects only when there is need to recover memory and might not do that for some object until the end of the program. And even for CPython GC algorithm may change in the future as reference counting isn't very efficient.

  • if exception is thrown when closing file on file object destruction, you can't really do anything about it because you won't know.

Tomek Szpakowicz
So, can I infer in the general sense that relying on the specifics of how garbage collection is implemented in the version of Python that I'm using is a Bad Idea and not Pythonic, and thus that is why the line of code I have in the question is incorrect?
Brent Newey
@Brent: It isn't necessarily incorrect (if you __decide__ to depend on specific behaviour of your implementation).I don't know about Pythonic ;-).But in any managed environment relying on garbage collector (tuned to free just memory) to clean up other resources is wrong direction.Of course if it's just short script _and_ you simply read file (like in your example) it's OK to let GC or even OS close the file.
Tomek Szpakowicz
+1  A: 

For the cpython implementation of python: yes, it is guaranteed to be closed when its reference count goes to zero.

For python as an abstract language (e.g., including Jython, IronPython, etc): no, it is not guaranteed to be closed. In particular, an implementation of Python may choose not to use reference counting, but to use some other form of GC.

References:

Edward Loper