== The anatomy of a hack to get around _try:_/_finally:_ and generators Suppose that you have the Python [[try:/finally: problem TryFinallyAndGenerators]] and need to get around it, specifically you need to both be a generator and have your _finally:_ run immediately. Taken from [[here http://jimmyg.org/blog/2009/using-yield-statements-in-wsgi-middleware-can-be-very-harmful.html]], one answer is: > def foo(bar): > try: > def output(): > ... compute with bar ... > yield res > ... > > return output() > finally: > print "finalizing" (Now, there is a lot of things that this doesn't help with; the actual computation hasn't finished, so you can't do anything in the _finally:_ that would destroy its ability to work.) I find this confusing enough that it's worthwhile walking through why it works. It goes like this: The _output()_ function is two things; it is both a generator and a closure. As a closure, it captures the arguments that _foo()_ was called with, so that it can do computation with them. As a generator, [[calling it doesn't run any of its code WhenGeneratorsRun]] but instead causes Python to immediately return an iterator object that is in turn effectively capturing the output() closure. The _foo()_ function then returns this iterator object and as part of returning, executes its own _finally:_ clause. (The shorter way of putting this is that returning the result of calling a generator function does not make you a generator function yourself, and thus your _finally:_ will run normally and immediately.) Obviously, you don't have to move all of the code into the _output()_ closure. In some situations you might have a lot of things that you do before you can return the first result, and the more you do in the main function the more resources you can release when it returns.