Python:在不同的命名空间中动态导入模块

时间:2012-04-13 19:59:40

标签: python namespaces import

import v_framework as framework
framework.loadModules(["Maintenance"])
framework.Maintenance.showPage()

framework我有:

def loadModules(aModules):
    d_utility = {"Maintenance":"COOl_M_PAGE"}
    for module in a_aModules:
        exec("import " + d_utility[module] + " as " + module)

执行loadModules时,它会导入v_framework命名空间中的模块。由于我将v_framework导入framework,我认为我应该可以使用framework.Maintenance来导入模块。但它不会那样工作。    有没有办法做我想做的事情?或者,有没有办法在命名空间中导入模块而不是执行exec的模块?

2 个答案:

答案 0 :(得分:1)

当您在函数内部import时,模块将照常导入/执行,但您导入的名称是函数的本地名称,就像在函数内指定的任何其他变量一样。

>>> def test_import():
...    import os
...    print os
...
>>> test_import()
<module 'os' from '/usr/lib/python2.7/os.pyc'>
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

os已导入,您仍然可以通过sys.modules访问它:

>>> import sys
>>> sys.modules['os']
<module 'os' from '/usr/lib/python2.7/os.pyc'>
>>> os = sys.modules['os']
>>> os
<module 'os' from '/usr/lib/python2.7/os.pyc'>

快速而肮脏的方式来做你想做的事就是这样的; exec将可选映射用作本地和全局变量。所以你可以做到

def loadModules(aModules):
    d_utility = {"Maintenance":"COOl_M_PAGE"}
    for module in aModules:
        exec ('import %s as %s' % (d_utility[module], module)) in globals()

虽然这很难看,可能还有安全隐患等。正如jadkik94所提到的,有些库提供了更清晰的方法来处理这个问题。

答案 1 :(得分:0)

有动态导入模块的库。您可以使用importlib(另一个可能有用的是pkgutil)。现在,对于你的情况,我想这可以做到这一点:

import importlib
mods = {}
def loadModules(aModule):
    global mods
    mods[module] = importlib.import_module(d_utility[module])
    # or maybe globals()[module] = ... would work also (exactly as you expect it to

UPDATE:exec修改函数的本地名称空间,而不是全局名称空间(我认为)。

希望它有所帮助。 :)