[Python-ideas] Avoiding nested for try..finally: atexit for functions?

Paul Moore p.f.moore at gmail.com
Wed Oct 19 15:57:21 CEST 2011


On 19 October 2011 03:14, Nikolaus Rath <Nikolaus at rath.org> wrote:
> Hello,
>
> I often have code of the form:
>
> def my_fun():
>    allocate_res1()
>    try:
>       # do stuff
>       allocate_res2()
>       try:
>           # do stuff
>           allocate_res3()
>           try:
>               # do stuff
>           finally:
>               cleanup_res3()
>       finally:
>           cleanup_res2()
>    finally:
>        cleanup_res1()
>
>    return
>
> With increasing number of managed resources, the indentation becomes
> really annoying, there is lots of line noise, and I don't like the fact
> that the cleanup is so far away from the allocation.
>
> I would much rather have something like this:
>
> def my_fun():
>    allocate_res1()
>    atreturn.register(cleanup_res1)
>    # do stuff
>    allocate_res2()
>    atreturn.register(cleanup_res2)
>    # do stuff
>    allocate_res3()
>    atreturn.register(cleanup_res3)
>    # do stuff
>    return
>
> Has the idea of implementing such "on return" handlers ever come up?
> Maybe there is some tricky way to do this with function decorators?

Here's a "tricky way with decorators" :-) :

>>> def withexit(f):
...     ex = []
...     def atex(g): ex.append(g)
...     def wrapper():
...         f()
...         for g in ex: g()
...     wrapper.atex = atex
...     return wrapper
...
>>> def p1(): print "one"
...
>>> def p2(): print "two"
...
>>> @withexit
... def ff():
...     print 1
...     ff.atex(p1)
...     print 2
...     ff.atex(p2)
...     print 3
...
>>> ff()
1
2
3
one
two
>>>

Paul.



More information about the Python-ideas mailing list