2012-04-13 48 views
0
import v_framework as framework 
framework.loadModules(["Maintenance"]) 
framework.Maintenance.showPage() 

framework我:的Python:動態地在不同的命名空間導入模塊

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_frameworkframework,我想我應該可以使用導入的模塊使用framework.Maintenance。但是這種方式不行。 有沒有辦法做到我想要做的事情?或者,有沒有辦法導入除執行exec之外的命名空間中的模塊?

回答

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修改函數的局部命名空間,而不是全球性的(我認爲)。

希望它有幫助。 :)

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所提到的,有些庫提供了更好的方法來處理這個問題。

+0

它在Python3中工作嗎? – Eduardo 2012-07-07 12:36:03