Exec, closures and scopes
closures, python, scope
Solution
It has to do with the fact that
gl = globals()
gl.update({'f':f})
in all cases works on the same object.
So the global `f()` is exchanged with a new one, and is called. The old one, along with its closure, gets lost.
gl = dict(globals())
gl.update({'f':f})
prevents that by copying the `globals()` dict.
Problem
Let's say I want to implement an identity decorator with exec (ie, it shouldn't do absolutely nothing to a function without parameters). When I try to define a closure using that decorator, the scope survives the end of the f_factory function and changes what comes next. I want to understand why does the last print return "1b" and not "1". ``` def exec_identity(f): gl = globals() gl.update({'f':f}) exec "def idfun(): return f()" in gl, locals() return idfun class CallableClass(object): def __init__(self, s): self.s = s def make_callable(self): def f_factory(s): def f(): print s return exec_identity(f) #return f return f_factory(self.s) c1 = CallableClass("1") f1 = c1.make_callable() f1() c1.s = "1b" f1() f1b = c1.make_callable() f1b() f1() """ Result: 1 1 1b 1b """ ``` I know that if I can leave the exec statement like this for it to work as expected: ``` exec "def idfun(): return f()" in {'f':f}, locals() ```