2013-09-27 3 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'> 

Однако я предпочел бы не использовать Exec(), потому что его довольно плохая практика и кажется ненужным, когда импортные механизмы питоны доступны уже через __import__, imp и importlib модулей ,

Есть ли способ в 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 не может быть модулем.

Heres функция, которая использует 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 является правильным, но, тем не менее, включает это для полноты, и это может помочь другим, столкнувшимся с той же проблемой.

Смежные вопросы