从模块导入子模块及其名称

RNA*_*RNA 3 python python-import

prepared_db我有一个在子模块中调用的函数db.db_1

from spam import db

submodule_name = "db_1"
func_name = "prepare_db"
func = ...
Run Code Online (Sandbox Code Playgroud)

如何通过上面上下文中的子模块名称和函数名称来获取函数?

更新

为了回应 @histrio 的答案,我可以验证他的代码适用于os模块。但在这种情况下它不起作用。创建示例:

$ mkdir -p spam/db
$ cat > spam/db/db_1.py
def prepare_db():
    print('prepare_db func')
$ touch spam/db/__init__.py
$ PYTHONPATH=$PYTHONPATH:spam
Run Code Online (Sandbox Code Playgroud)

现在,您可以正常导入:

>>> from spam.db.db_1 import prepare_db
>>> prepare_db()
prepare_db func
Run Code Online (Sandbox Code Playgroud)

但如果你动态执行此操作,我会收到此错误:

>>> getattr(getattr(db, submodule_name), func_name)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-1b6aa1216551> in <module>()
----> 1 getattr(getattr(db, submodule_name), func_name)

AttributeError: module 'spam.db.db_1' has no attribute 'prepared_db'
Run Code Online (Sandbox Code Playgroud)

his*_*rio 6

这很简单。您可以将模块视为对象。

import os

submodule_name = "path"
func_name = "exists"

submodule = getattr(os, submodule_name)
function = getattr(submodule, func_name)
function('/home') # True
Run Code Online (Sandbox Code Playgroud)

或者[只是为了好玩,不要这样做]

fn = reduce(getattr, ('sub1', 'sub2', 'sub3', 'fn'), module)
Run Code Online (Sandbox Code Playgroud)

更新

import importlib
submodule = importlib.import_module('.'+submodule_name, module.__name__)
function = getattr(submodule, func_name)
Run Code Online (Sandbox Code Playgroud)