自定义python模块中的分层命名空间

时间:2012-06-27 03:24:23

标签: python module namespaces

尝试搜索网站,但无法找到问题的答案:

假设我有一个名为mymodule.py的模块,其中包含:

def a():
    return 3

def b():
    return 4 + a()

然后以下工作:

import mymodule
print(mymodule.b())

但是,当我尝试动态定义模块内容时:

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')
exec(my_code, globals(), mymodule.__dict__)
print(mymodule.b())

然后它在函数b()中失败:

Traceback (most recent call last):
File "", line 13, in <module>
File "", line 6, in b
NameError: global name 'a' is not defined

我需要一种方法来保留模块中的分层命名空间搜索,除非模块驻留在磁盘上,否则它似乎会失败。

关于差异的任何线索?

谢谢, 罗布。

2 个答案:

答案 0 :(得分:3)

你很亲密。你需要告诉exec在不同的命名空间中工作(参见python 3.x底部的注释):

exec my_code in mymodule.__dict__

完整示例:

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')

exec my_code in mymodule.__dict__
print(mymodule.b())

这就是说,我以前没用过这个,所以我不确定是否有任何奇怪的副作用,但看起来它对我有用。

此外,在这里的python文档中有一个关于'exec in ...'的小模糊:http://docs.python.org/reference/simple_stmts.html#the-exec-statement

<强>更新

您的原始尝试无法正常工作的原因是您传递的是当前模块的globals()字典,这与您的新模块应使用的globals()不同。

这个exec行也有效(但不像'exec in ...'样式那样漂亮):

exec(my_code, mymodule.__dict__, mymodule.__dict__)

更新2:由于exec现在是python 3.x中的一个函数,它没有'exec in ...'样式,因此必须使用上面的行。

答案 1 :(得分:0)

这不是exec()的设计方式。 exec()实际上并没有将它运行的代码“放入”任何模块中 - 它在调用exec()的模块空间中运行它。