简体   繁体   English

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

[英]Python: import modules dynamically in different namespace

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

In framework I have: framework我有:

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

When loadModules is executed, it imports the modules in the v_framework namespace. 当执行loadModules ,它将模块导入v_framework命名空间中。 Since I am importing v_framework as framework , I think I should be able to use the imported module using framework.Maintenance . 由于我将v_framework导入为framework ,因此我认为我应该能够使用framework.Maintenance使用导入的模块。 But it does not work that way. 但这不是那样的。 Is there a way to do way to do what I'm trying to do? 有没有办法做我想做的事情? Alternatively, is there any way to import modules in a namespace other than the one where exec is executed? 或者,除了执行exec方法外,是否有其他方法可以在命名空间中导入模块?

When you import inside a function, the module is imported/executed as normal, but the name you import under is local to the function, just like any other variable assigned inside a function. 当您在函数内部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 has been imported though, and you can still access it through sys.modules : 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'>

A quick and dirty way to do what you want would be something like this; 一种快速而肮脏的方式来做您想要的事情是这样的; exec takes an optional mapping to be used as the local and global variables. exec采用一个可选的映射用作局部变量和全局变量。 So you could do 所以你可以做

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

Though this is ugly and probably has security implications or something. 尽管这很丑陋,并且可能会对安全性产生影响。 As jadkik94 mentions, there are libraries that provide cleaner ways to deal with this. 正如jadkik94所提到的,有一些库提供了更干净的方法来处理此问题。

There are libraries for importing modules dynamically. 有用于动态导入模块的库。 You could use importlib (and another one that might be useful is pkgutil ). 您可以使用importlib (另一个可能有用的是pkgutil )。 Now, for your case, I guess this would do the job: 现在,对于您的情况,我想这可以完成工作:

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 modifies the function's local namespace, not the global one (I think). 更新:exec修改函数的本地名称空间,而不是全局名称空间(我认为)。

Hope it helps. 希望能帮助到你。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM