On 19 October 2011 03:14, Nikolaus Rath Nikolaus@rath.org wrote:
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()
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