I use closures quite a lot in python, but the variable lifetime semantics of closures are undocumented as far as I can tell. For example, consider the following code:
def f(): a=1 b=1 def g(): return b return g
If we call ‘f’ and store the value, ‘b’ will be kept alive. Is ‘a’ kept alive? A naive implementation of closures might store a reference to the entire stack frame of ‘f’ inside the ‘g’ closure, causing ‘a’ to live even though it will never be used. This would be very bad, since generating a closure inside a long function could potentially cause a large memory leak. I wouldn’t expect this since python is implemented by smart people, but it’s worth checking.
Happily, it appears the variable lifetime semantics are as expected. Here’s a test program:
class A(object): def __init__(self,name): self.name=name print 'creating',name def __del__(self): print 'destroying',self.name def f(): a=A('a') b=A('b') c=A('c') def g(): print 'inspecting',b.name def h(): print 'inspecting',c.name return g,h g,h=f() print 'only b and c should be alive' del h print 'only b should be alive' g() del g print 'done'
The output of this program in CPython is
creating a creating b creating c destroying a only b and c should be alive destroying c only b should be alive inspecting b destroying b done
All variables die at the correct times, so CPython appears to have correct lifetime semantics in the presence of closures.