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

how to import a submodule in Python (without `exec`)

我想事先导入子模块而不知道它的名字,

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

不能正常工作,返回os,而不是os.path

我想出了这个解决方案。

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

这给出了结果:

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

但是我宁愿不使用exec()因为它的相当糟糕的做法,并且当Pythons导入机制已经通过__import__impimportlib模块可用时似乎是不必要的。

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


使用importlib.import_module

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

这应该在python2.7 +和3.1+中工作。


请注意,如果要执行:from A import B as C作为函数调用,importlib.import_module将不会始终有效,因为B可能不是模块。

下面是一个使用importlib和getattr的函数。

1
2
3
4
5
def my_import_from(mod_name, var_name):
    import importlib
    mod = importlib.import_module(mod_name)
    var = getattr(mod, var_name)
    return var

所以这:

1
from os.path import dirname as var

可以替换为:

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

这避免了exec并允许子模块和模块中定义的任何变量。

由于我的问题明确表示导入一个子模块,@ Bakuriu的答案是正确的,但是包括这个完整性,它可能会帮助遇到同样问题的其他人。