[Python-ideas] Automatic context managers
Ronald Oussoren
ronaldoussoren at mac.com
Wed Apr 24 11:23:09 CEST 2013
On 24 Apr, 2013, at 10:59, anatoly techtonik <techtonik at gmail.com> wrote:
> Long time no see, all. :P
>
> PySide Qt binding have an interesting property - when you create widgets, you need to assign them to variables. When such variable is lost, object is immediately destroyed.
>
> I often use this one-shot code in setup.py:
> ...
> long_description = open('README.txt').read(),
> ....
>
> Which probably leaves the README.txt file open until the setup.py exits. So, the idea is to close the file as soon as the variable is lost.
The file is automaticly closed as soon as the file object is garbage collected. In your example CPython would currently collect at the end of the read call (unles there is an exception) because of the reference counting garbage collector, but other implementations have other garbage collectors and can collect the file object (much) later.
>
> I don't know why it was not implemented in the first place. Any ideas?
It was implemented a long time ago. The with statement was added because relying on automatic resource cleanup by a destructor might clean up the resource too late (for example because the file object is referenced by a local variable in a frame that's referenced by an exception).
>
> Depending on the answer to the above, the solution can be different. I assume that this was done for a reason (probably immediate garbage collection is too expensive), but confirmation is welcome. Meanwhile the solution can be implemented with auto context manager, which __exit__ method is automatically called when all links to created object are lost.
>
> Difference from usual "with something" is that it is transparent to the user (leaves less details to worry about) and makes code more beautiful -- in the example above the assignment is made inside setup(...) parameter assignment. An example with ordinary "with" statement would look like:
>
> with open('README.txt') as readme:
> setup(
> ....
> long_description=readme.read(),
> ....
> )
In python 3.3 and later you can use contexlib.ExitStack:
with contextlib.ExitStack() as stack:
setup(
...
long_description = stack.enter_context(open('README.txt')).read(),
...
)
But for simple scripts like a setup.py I wouldn't worry too much about closing files later than expected.
Ronald
>
> The nesting level increases with every new file you need to read.
> Another variation is intermediate variables, which is also less nice.
>
> with open('README.txt') as readme:
> content = readme.read()
> setup(
> ....
> long_description=content,
> ....
> )
>
> --
> anatoly t.
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
More information about the Python-ideas
mailing list