exec doesn't pick up variables from closure

谁说胖子不能爱 提交于 2019-12-01 02:55:41

问题


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 ...


回答1:


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_globals1 (inspired by this):

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

Nice.

1It would be namespace['bar'].__globals__.update on python3.x



来源:https://stackoverflow.com/questions/20134417/exec-doesnt-pick-up-variables-from-closure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!