如何在Python中导入子模块(没有`exec`)

时间:2013-09-27 06:30:03

标签: python python-3.x python-import

我想在不事先知道其名称的情况下导入子模块,

>>> __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(),因为当Pythons导入机制已经通过__import__impimportlib模块可用时,这种做法相当糟糕并且似乎没有用。

Python3.x中有没有办法通过函数调用来进行这种导入,而不是使用exec()

2 个答案:

答案 0 :(得分:4)

使用importlib.import_module

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

这应该适用于python2.7 +和3.1 +。

答案 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的答案是正确的,但是包括这一点是为了完整性,它可能会帮助遇到同样问题的其他人。