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>
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.
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 :)
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?
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.
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.
精彩评论