使用exec
使用此测试代码(使用Python 3.4):
vals = {}
exec('def fun(): print("Hello from fun")', vals)
exec('def main(): fun()', vals)
vals['main']()
输出结果为:
Hello from fun
但是我没想到这会起作用,因为我假设fun
和main
被解释为单独的代码片段而没有共同的命名空间来解析main
到{{fun
中的引用1}}。
那么main
的执行如何解决对fun
的引用?
添加基于对问题的理解。对于print
和id
vals
为globals
,很明显这两个函数看到相同的全局变量:
vals = {}
print('id(vals):', id(vals))
exec('def fun(): print("fun id(globals()):", id(globals())); print("Hello from fun")', vals)
exec('def main(): print("main id(globals()):", id(globals())); fun()', vals)
vals['main']()
给出了:
id(vals):32271016
主要身份证(globals()):32271016
fun id(globals()):32271016
Hello from fun
因此vals
用作exec
中代码的全局变量,从而提供连接,如@Dunes和其他描述的注释。感谢。
答案 0 :(得分:3)
通过向vals
两个函数提供exec
,您已经提供了公共命名空间。 exec
的第二个参数是在任何执行的代码中用于全局引用的字典。执行第一个语句时,它会创建fun
并将其存储在全局命名空间(vals
)中。因此,当main
尝试查找fun
时,它发现它不是局部变量,因此尝试在其全局变量中查找fun
(也是vals
) 。由于fun
中存在vals
,因此查找工作并检索和调用该函数。如果为每个exec
提供了自己的dict
,那么这将无效。如果你不提供vals
那么调用exec
的当前全局变量将被用作全局变量(因此这仍然有用)。