我需要在Python中执行一些动态生成的代码,并确保此代码可以访问某些自定义全局值,例如“bar”。基于python文档,我收集了以下测试代码:
def foo() : print( globals() )
exec "foo()" in dict( globals(), bar = 1 )
根据文档,在foo()
中调用exec
并bar
添加到范围中的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}}?
答案 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 )