Python:如何在自定义范围内使用'exec'?

时间:2012-03-07 12:38:56

标签: python

我需要在Python中执行一些动态生成的代码,并确保此代码可以访问某些自定义全局值,例如“bar”。基于python文档,我收集了以下测试代码:

def foo() : print( globals() )
exec "foo()" in dict( globals(), bar = 1 )

根据文档,在foo()中调用execbar添加到范围中的bar会在globals()内部foo()内列出{'__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Users\\Eye\ \Documents\\first.py', '__package__': None, '__name__': '__main__', 'foo': <func tion foo at 0x01DD40F0>, '__doc__': None} 。但实际输出是:

bar

此处没有bar :(。如何在exec中执行的代码中访问{{1}}?

4 个答案:

答案 0 :(得分:3)

(我在这里跳过一个关于exec的普遍不好和不安全的常见咆哮

如果您尝试这样做:

exec "print globals().get('bar')" in dict( globals(), bar = 1 )

你会发现它按预期工作。

当你定义一个函数时,它与它的模块的命名空间绑定,这就是它所看到的全局变量。您可以通过foo.func_globals覆盖这些绑定。这就是函数如何通过全局变量访问模块内部,但无法看到调用者的环境(定义了bar)。

答案 1 :(得分:2)

根据the documentation,当从函数中调用globals()时,它返回定义函数的模块的字典

如果创建新的全局AND并将其作为参数传递,则应该能够动态调用函数。例如,

def foo(bar):
  print bar

exec "foo(bar)" in dict(globals(), bar = "hello")

答案 2 :(得分:0)

抱歉,这有什么问题?

def foo() : print( globals() )
bar = 1
exec "foo()"
{'bar': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x7fd1b3954ed8>, '__doc__': None}

答案 3 :(得分:0)

我找到了合适的解决方案:

def foo() : print( foo.bar )
exec "foo.bar = bar\n" + "foo()" in dict( globals(), bar = 1 )