python 动态从模块导入函数按字符串

python dynamic from module import function by string

源码为(简化举例):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from utils.func_a import func_a as _func_a
from utils.func_b import func_b as _func_b
def func_a():
    _func_a()

def func_b():
    _func_b()

if __name__ == '__main__':
    func_a()

现在我只调用了func_a,或者可能是func_b,这取决于配置。

所以我想动态做 from ... import ...,比如:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def func_a():
    _func_a()

def func_b():
    _func_b()

if __name__ == '__main__':
    keys = ['func_a']
    for k in keys:
        mod_n = func_n = k
        from utils.<mod_n> import <func_n> as _<func_n>   # TODO
    func_a()

但不知道如何实现?

我想的是在 func_X():

中导入
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def func_a():
    from utils.func_a import func_a as _func_a
    _func_a()

def func_b():
    from utils.func_b import func_b as _func_b
    _func_b()

if __name__ == '__main__':
    func_a()

但是这种方式每次调用函数的时候都会导入


补充:

我试过__import__/importlib,但无法实现这个条件

__import__ 是一个内置函数,它将模块名称作为字符串,returns 模块作为对象。见 the documentation:

__import__(name[, globals[, locals[, fromlist[, level]]]])

The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name.

在我问这个问题之前,我已经尝试了__import__importlib,但是无法写出代码。

感谢@machine-yearning,我阅读了 __import__ 的整个文档。

这是我的解决方案:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
def func_a():
    _func_a()

def func_b():
    _func_b()

if __name__ == '__main__':
    keys = ['func_a']
    for k in keys:
        mod_n = func_n = k
        _temp = __import__('utils.'+mod_n, fromlist=[func_n])
        _func = getattr(_temp, func_n)
        new_func_n = '_{0}'.format(k)
        setattr(sys.modules[__name__], new_func_n, _func)

    func_a()