使用任意变量作为“exec”的命名空间



使用exec(使用Python 3.4)进行此测试代码:

vals = {}
exec('def fun(): print("Hello from fun")', vals)
exec('def main(): fun()', vals)
vals['main']()

输出为:

你好,来自有趣的

但我没想到这会起作用,因为我假设funmain被解释为单独的代码段,而没有公共命名空间来解析mainfun中的引用。

那么main的执行如何解决对fun的引用呢?


基于加法的理解问题。对于valsglobals,使用idprint,可以清楚地看出,这两个函数看到相同的全局:

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

主id(globals()):32271016

fun id(globals()):32271016

你好,来自有趣的

因此,vals被用作exec中代码的全局变量,从而给出连接,如@Dunes和其他注释所述。谢谢

通过向两个exec函数提供vals,您提供了通用名称空间。exec的第二个参数是一个字典,用于执行的任何代码中的全局引用。当执行第一条语句时,它创建fun并将其存储在全局名称空间(vals)中。因此,当main尝试查找fun时,它发现它不是局部变量,因此尝试在其全局(也是vals)中查找fun。由于fun存在于vals中,因此查找工作正常,并且检索和调用函数。如果给每个exec它自己的dict,那么这将不起作用。如果不提供vals,那么调用exec的当前全局变量将用作全局变量(因此这仍然有效)。

相关内容

  • 没有找到相关文章

最新更新