2013-09-27 29 views
3

我想進口的子模塊事先不知道它的名字,如何導入在Python的子模塊(不`exec`)

>>> __import__("os.path") 
<module 'os' from '/usr/lib/python3.3/os.py'> 

正如您所料不工作,返回os,不os.path

我想出了這個解決方案。

def import_submodule(mod, submod): 
    ns = {} 
    exec_str = "from %s import %s as submod" % (mod, submod) 
    exec(exec_str, ns, ns) 
    return ns["submod"] 

這給出結果:

>>> import_submodule("os", "path") 
<module 'posixpath' from '/usr/lib/python3.3/posixpath.py'> 

然而,因爲當蟒蛇進口機制可已通過__import__impimportlib模塊及其很壞的做法,似乎沒有必要我寧可不使用EXEC() 。

在Python3.x中有沒有辦法通過函數調用來完成這種導入,而不是使用exec()

+0

可能重複的[如何動態加載Python類](http://stackoverflow.com/questions/547829/how-to-dynamically-load-a-python-class) –

+0

請注意'name.split( '。')',然後循環使用'getattr()'來檢索'子對象'; '.path'在你的情況下。 –

+0

將'os.path'放在你的例子可能會導致你瘋狂的追逐,因爲[它不一定像其他模塊一樣工作](http://stackoverflow.com/a/2725195/1222578) – Marius

回答

3

使用importlib.import_module

>>> import importlib 
>>> importlib.import_module('os.path') 
<module 'posixpath' from '/usr/lib/python2.7/posixpath.pyc'> 

這應該在python2.7 +和3.1+工作。

3

請注意,如果你想做:from A import B as C作爲一個函數調用,importlib.import_module不會總是工作,因爲B可能不是一個模塊。

繼承人一個使用importlib和getattr的函數。

def my_import_from(mod_name, var_name): 
    import importlib 
    mod = importlib.import_module(mod_name) 
    var = getattr(mod, var_name) 
    return var 

所以這個:

from os.path import dirname as var 

可以用這個代替:

var = my_import_from("os.path", "dirname") 

避免了exec和允許兩個子模塊中的任何變量模塊中定義。

由於我的問題明確指出導入一個子模塊,所以@Bakuriu的回答是正確的,但包括這個完整性,它可能會幫助其他人遇到同樣的問題。