在自定义命名空间中调用execfile()会在'__builtin__'命名空间中执行代码

时间:2009-04-02 18:42:15

标签: python namespaces

当我调用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'

任何人都可以解释这种行为吗? 感谢

3 个答案:

答案 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)