Exec does not take variables from closure

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 level of the regular interpreter, we can find foo in bar.func_globals or bar.func_closure if in a function. I think I'm wondering why namespace['bar'] doesn't put foo in func_closure ...

+6
source share
1 answer

Turns out the answer was there all the time in docs :

If two separate objects are specified as global and local, the code will be executed as if it were embedded in the class definition.

Since I pass both globals and locals , it runs as if it were in a class.

 class Foo(object): foo = [1,2,3] @staticmethod def bar(): return foo[1] 

not surprisingly not working :).

For anyone interested in a workaround, you can insert namespace back into namespace['bar'].func_globals 1 ( inspired by this ):

 >>> namespace['bar'].func_globals.update(namespace) >>> namespace['bar']() 2 

Nice.

1 This will be namespace['bar'].__globals__.update in python3.x

+4
source

Source: https://habr.com/ru/post/958605/


All Articles