【问题标题】:hierarchical namespaces in custom python modules自定义 python 模块中的分层命名空间
【发布时间】:2012-06-27 03:24:22
【问题描述】:

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

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

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

有什么不同的线索吗?

谢谢, 抢。

【问题讨论】:

    标签: python module namespaces


    【解决方案1】:

    你已经接近了。您需要告诉 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 ...'样式,所以必须使用上面的行。

    【讨论】:

    • 是否有 python 3.x 版本的 "exec ... in " ?似乎无法在 exec() 函数中找到它。谢谢
    • 它看起来不像...查看我的更新,“不太漂亮”的版本应该在 3.x 中适合你(我还没有尝试过,所以让我知道如果它有效)
    • 好的,我已经在 python3 中测试了exec(my_code, mymodule.__dict__, mymodule.__dict__),它似乎工作正常。我也更新了我的答案以反映这一点。
    • 好吧,我试一试,看起来很有希望(我必须为我的原始项目修改一些东西)。非常感谢。
    【解决方案2】:

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

    【讨论】:

    • 那么有没有 exec() 的替代方法可以重现我需要的模块行为?谢谢
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多