3

尝试搜索该站点,但找不到我的问题的答案:

假设我有一个名为 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

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

关于有什么区别的任何线索?

谢谢,罗伯。

4

2 回答 2

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 ...' 样式,所以必须使用上面的行。

于 2012-06-27T03:59:02.237 回答
0

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

于 2012-06-27T03:45:25.083 回答