So recently I understand the concept of function closure.
def outer():
somevar = []
assert "somevar" in locals() and not "somevar" in globals()
def inner():
assert "somevar" in locals() and not "somevar" in globals()
somevar.append(5)
return somevar
return inner
function = outer()
somevar_returned = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
As much as I understand, the objective of function closure is to keep an active reference to the object, in order to avoid garbage collection of this object. This is why the following works fine :
del outer
somevar_returned_2 = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
assert id(somevar_returned) == id(somevar_returned_2)
The thing is (always as much as I understood) before the execution of the inner
function, Python rebuild the locals variables dictionary. This dictionary will contains :
- the function's closure names associated to their cell contents
- the function's parameters names associated to their default value or the parameter given (and it can overwrite the precedent names)
The question is where do Python store the name binding of the closure ? I can't find it anywhere.
Note: the function's attributes :
>>> print "\n".join("%-16s : %s" % (e, getattr(function, e)) for e in dir(function) if not e.startswith("_") and e != "func_globals")
func_closure : (<cell at 0x2b919f6bc050: list object at [...]>,)
func_code : <code object inner at [...], file "<stdin>", line 4>
func_defaults : None
func_dict : {}
func_doc : None
func_name : inner