Python方法中执行execfile()的方法

3

我有一个config.py脚本,其中包含前置信息。我可以使用execfile()函数读取配置文件的内容。

execfile("config.py")
print PREAMBLE
>>> "ABC"

然而,当在方法中调用execfile()时,我会遇到一个错误。

def a():
    execfile("config.py")
    print PREAMBLE

a()
>>> NameError: "global name 'PREAMBLE' is not defined"

什么出了问题,该如何解决?
2个回答

6
你需要将全局字典传递给 execfile,以实现相同的结果:
def a():
    execfile("config.py",globals())
    print PREAMBLE

a()
>>> "some string"

如果您不想污染全局命名空间,可以传递一个本地字典并使用它:
def a():
    config = dict()
    execfile('/tmp/file',config)
    print config['PREAMBLE']

a()
>>> "some string"

作为参考,上述两种情况中,/tmp/file 包含 PREAMBLE = "some string"


1
请注意,from whatever import a; a()不会将PREAMBLE加载到当前命名空间中,因为它使用了a的全局字典而不是调用它的人的全局字典。 - user2357112

2
问题在于当调用execfile()时代码所运行的命名空间。如果你研究文档,就会发现execfile()可以接受两个命名空间参数来代表全局和本地命名空间以执行代码。
在模块级别(即i.e.execfile()调用不是在函数内部时)模块全局命名空间用于这两个命名空间。从函数内部开始,模块全局变量被用作全局命名空间,而本地命名空间是函数调用命名空间(通常在调用返回后消失)。
因此,由于赋值优先绑定本地命名空间中的名称,执行文件将PREAMBLE设置在函数调用命名空间中,因此无法在模块级别找到它。
如果你的配置文件确实是Python代码,那么导入它们难道不可行吗?这样你只需使用import config然后在你的代码中引用config.PREAMBLE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接