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()