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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With