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

Nikolaus Rath Nikolaus at rath.org
Wed Oct 19 15:36:58 CEST 2011


Chris Rebert <pyideas-QkDgq5C4a+JWk0Htik3J/w at public.gmane.org> writes:
> On Tue, Oct 18, 2011 at 7:14 PM, 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.
>
> Use the `with` statement and context managers. They were added for
> this exact situation.
> See http://www.python.org/dev/peps/pep-0343/
>
> Resulting code will resemble:
>
> def func():
>     with alloc() as res1, alloc() as res2, alloc() as res3:
>         # do stuff

I think they're not for exactly this situation for two reasons:

1. This requires the alloc() functions to be context managers. If they're
not, then I need to code a wrapping context manager as well. It's
probably possible to write a generic wrapper that works for any cleanup
function, but the result is not going to look very nice.

2. If I don't want to allocate the resources all at the same time, the
indentation mess is still the same:

def func():
    with alloc() as res1:
       # do stuff
       with alloc() as res2:
           # do stuff
           with alloc() as res3:
               # do stuff

Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C



More information about the Python-ideas mailing list