当我调用execfile而不传递globals或locals参数时,它会在当前命名空间中创建对象,但是如果我调用execfile并为globals(和/或locals)指定一个dict,它会在__builtin__
中创建对象命名空间。
采用以下示例:
# exec.py
def myfunc():
print 'myfunc created in %s namespace' % __name__
exec.py是从main.py执行execfile的,如下所示。
# main.py
print 'execfile in global namespace:'
execfile('exec.py')
myfunc()
print
print 'execfile in custom namespace:'
d = {}
execfile('exec.py', d)
d['myfunc']()
当我从命令行运行main.py时,我得到以下输出。
execfile in global namespace:
myfunc created in __main__ namespace
execfile in custom namespace:
myfunc created in __builtin__ namespace
为什么在第二种情况下它在__builtin__
命名空间中运行?
此外,如果我尝试从__builtins__
运行myfunc,我会得到一个AttributeError。 (这是我希望发生的事情,但为什么__name__
设置为__builtin__
?)
>>> __builtins__.myfunc()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'myfunc'
任何人都可以解释这种行为吗? 感谢
答案 0 :(得分:4)
首先,__name__
不是命名空间 - 它是对它所属模块名称的引用,即:somemod.py - &gt; somemod.__name__ == 'somemod'
例外情况是,如果您从命令行运行模块作为可执行文件,那么__name__
是'__main __'。
在你的例子中,幸运的是,你的模块作为main运行,也称为main。
Execfile执行模块的内容而不将其作为模块导入。因此,__name__
没有设置,因为它不是一个模块 - 它只是一个执行的代码序列。
答案 1 :(得分:1)
execfile函数类似于exec语句。如果您查看documentation for exec,您会看到解释该行为的以下段落。
作为副作用,除了与执行代码设置的变量名对应的字典之外,实现可以将附加键插入到给出的字典中。例如,当前实现可以在键
__builtin__
(!)下添加对内置模块__builtins__
的字典的引用。
编辑:我现在看到我的答案适用于问题标题的一种可能的解释。我的回答不适用于实际问题。
答案 2 :(得分:1)
顺便说一句,我更喜欢使用__import__()
而不是execfile
:
module = __import__(module_name)
value = module.__dict__[function_name](arguments)
这在添加到PYTHONPATH时也很有效,因此可以导入其他目录中的模块:
sys.path.insert(position, directory)