I'm a little curious why the following code raises a NameError
.
>>> s = """
... foo = [1,2,3]
... def bar():
... return foo[1]
... """
>>> namespace = {}
>>> exec(s, {'__builtins__': None}, namespace)
>>> print namespace
{'foo': [1, 2, 3], 'bar': <function bar at 0x7f79871bd0c8>}
>>> namespace['bar']()
At the normal interpreter level, we can find foo
in bar.func_globals
or bar.func_closure
if in a function. I guess I'm wondering why namespace['bar']
doesn't put foo
in func_closure
...
It turns out that the answer was there all along in the docs:
If two separate objects are given as globals and locals, the code will be executed as if it were embedded in a class definition.
Since I'm passing in both globals
and locals
, it executes as if it were in a class.
class Foo(object):
foo = [1,2,3]
@staticmethod
def bar():
return foo[1]
not surprisingly doesn't work either :).
For anyone interested in a workaround, you can inject namespace
back into namespace['bar'].func_globals
1 (inspired by this):
>>> namespace['bar'].func_globals.update(namespace)
>>> namespace['bar']()
2
Nice.
1It would be namespace['bar'].__globals__.update
on python3.x