pyInTheSky
pyInTheSky

Reputation: 1469

Why does the context hang around after a with statement?

I would like to know why a file object opened using with statement or in a block, remains in scope after exit. Are <closed file> objects ever cleaned up?

>>> with open('test.txt','w') as f:
...     f.write('test')
...
>>> f
<closed file 'test.txt', mode 'w' at 0x00E014F0>
>>> f.close()


>>> if True:
...     fal = open('demo.txt','w')
...     fal.write('stuff')
...     fal.close()
...
>>> fal
<closed file 'demo.txt', mode 'w' at 0x00E015A0>

Upvotes: 7

Views: 1161

Answers (5)

user355252
user355252

Reputation:

In Python new scopes (aka namespaces) are only created for modules, classes and functions, but not for any other statement, especially not for with and if blocks. Identifiers bound within the body of with or for statements are consequently bound in the inner-most surrounding scope, which is the top-level scope of the interactive interpreter in your case. Identifiers are bound in a scope as long as this scope is valid, or until they are explicitly removed from the scope (by using del as in del fal).

Objects can only be cleaned up when they are not longer referenced. The actual moment, in which this object is really cleaned up, is however undefined. Python uses garbage collection for memory management, and doesn't enforce a specific strategy. In CPython, which uses reference counting, objects are immediately cleaned up, once the last reference goes out of scope. Alternative implementations like PyPy or Jython use more advanced garbage collectors, which clean up unreferenced objects at arbitrary points of time.

This means, that in your example the objects bound to f and fal are bascially never cleaned up, because the top-level scope of the interactive interpreter does naturally exist as long as the interpeter is running. Beware however, that this is not actually a problem, because they are nevertheless correctly closed and do not claim any file resource anymore, but only some memory.

Upvotes: 16

Wooble
Wooble

Reputation: 90007

with and if don't create a new scope, local variables are only created within functions, classes, and modules. See What's the scope of a Python variable declared in an if statement?

Upvotes: 2

Foo Bah
Foo Bah

Reputation: 26271

Python's with statement calls the file class's __exit__ method [which ,in the case of files, closes them]. It does not delete the object; it is cleaned up only when you explicitly clean it up or close the program/interpreter.

Upvotes: 0

extraneon
extraneon

Reputation: 23960

The name will remain in scope untill you leave the scope.

If you want the object cleaned up, assign a different value to the name, like

f = None

This does not close the file!

It is a good habit to make the scopes limited by structuring the program in to functions ( and possibly classes ). That makes it more readable and makes unbound objects (no names in scope which refer to the object ) elegible for garbage collection.

This is usually not an issue when you're using the prompt though :)

Upvotes: 4

Aphex
Aphex

Reputation: 7500

The file object, like any other object, 'hangs around' for the duration of your program, until it's deleted (its __del__ method is called).

del f will cause f to be garbage collected by Python's garbage collector. This happens automatically when you exit a scope, your script terminates, or in your example, the interpreter session ends.

Upvotes: 0

Related Questions