动态导入脚本列表 - Python
Importing a List of Scripts Dynamically - Python
假设我有 N python 个文件(每个文件都有一个 main
函数),文件结构如下:
tools \
|_ tool_1.py
|_ tool_2.py
...
|_ tool_N.py
此外,我有这样的数据结构:
files = [
{"path":"tools/tool_1.py", "alias" : "tools__tool_1"}
{"path":"tools/tool_2.py", "alias" : "tools__tool_2"}
...
{"path":"tools/tool_N.py", "alias" : "tools__tool_N"}
]
如何将这些文件动态导入到单个 python 文件中?工具的数量会随着时间的推移而增加,手动为每个工具添加一行是不可行的。
那么我该如何转换:
from tools.tool_1 import main as tools__tool_1
from tools.tool_2 import main as tools__tool_2
...
from tools.tool_N import main as tools__tool_N
到这个?
for file in files:
from file["path"] import main as file["alias"]
您需要调用exec()函数。请参阅下面的示例:
exec('from datetime import datetime')
print(datetime.now())
所以你的情况是:
for file in files:
exec(f'from {file["path"]} import main as {file["alias"]}')
好的,首先是几个免责声明:(1) 动态导入模块可能是也可能不是您真正需要的。我自己这样做了,但在我的例子中,我有一个包含大约 100 个不同模型的库,以及一个通用驱动程序,该驱动程序根据我提供的命令行选项动态加载其中一个模型。要点是我一次不需要加载多个模块,因此动态加载一个模块是有意义的。
并且 (2) 我远不是导入模块和包的专家,但我通常能够让它做我想做的事。
话虽如此,如果您认为动态导入模块是您想要的,那么这应该适合您。请注意,我试图为您创建一个完整的示例:
import importlib
files = [
{"path" : "tools.tool_1", "name" : "tools__tool_1"},
{"path" : "tools.tool_2", "name" : "tools__tool_2"},
{"path" : "tools.tool_3", "name" : "tools__tool_3"}
]
module_dict = {}
main_dict = {}
for file_desc in files:
path = file_desc["path"]
name = file_desc["name"]
module = importlib.import_module(path)
module_dict[name] = module
main_dict[name] = module.main
main_dict["tools__tool_1"]()
在此示例中,三个模块都位于目录 tools
中。这些模块是 tool_1
、tool_2
和 tool_3
。它们以 tools__tool_1
等名称导入并存储在字典中。注意:您可以简单地使用 tool_1
等来表示这些名称,除非您需要使用 tools__
来限定它们因为您想将其他目录中的模块加载到相同的词典中。
请注意,这些导入中的 none 对您的全局命名空间有任何影响。模块作为对象导入,它们(或它们的 main
函数)仅存储在字典中。
关于你需要什么,我不完全确定你想要什么,所以我创建了两个词典。第一个是 module_dict
,它导入整个模块。第二个是 main_dict
,它只包含来自每个导入模块的 main
函数,如原始 post 中所述。
请注意,每个模块只导入一次。如果您只需要其中一本词典,只需删除不需要的词典即可。
无论如何,假设您想从 tools.tool_1
调用 main
。您可以从 main_dict
执行此操作,如下所示:
main_dict["tools__tool_1"]()
如果您想从 module_dict
调用它或任何其他函数,您可以这样做:
module_dict["tools__tool_1"].main()
您基本上可以从 module_dict
访问模块中的所有内容,但如果您只想访问 main
,那么您可以只使用 main_dict
.
同样,这里可能比您需要的更多,但我不完全确定您打算如何使用它。如果您只需要其中一本词典,只需去掉另一本即可。
假设我有 N python 个文件(每个文件都有一个 main
函数),文件结构如下:
tools \
|_ tool_1.py
|_ tool_2.py
...
|_ tool_N.py
此外,我有这样的数据结构:
files = [
{"path":"tools/tool_1.py", "alias" : "tools__tool_1"}
{"path":"tools/tool_2.py", "alias" : "tools__tool_2"}
...
{"path":"tools/tool_N.py", "alias" : "tools__tool_N"}
]
如何将这些文件动态导入到单个 python 文件中?工具的数量会随着时间的推移而增加,手动为每个工具添加一行是不可行的。
那么我该如何转换:
from tools.tool_1 import main as tools__tool_1
from tools.tool_2 import main as tools__tool_2
...
from tools.tool_N import main as tools__tool_N
到这个?
for file in files:
from file["path"] import main as file["alias"]
您需要调用exec()函数。请参阅下面的示例:
exec('from datetime import datetime')
print(datetime.now())
所以你的情况是:
for file in files:
exec(f'from {file["path"]} import main as {file["alias"]}')
好的,首先是几个免责声明:(1) 动态导入模块可能是也可能不是您真正需要的。我自己这样做了,但在我的例子中,我有一个包含大约 100 个不同模型的库,以及一个通用驱动程序,该驱动程序根据我提供的命令行选项动态加载其中一个模型。要点是我一次不需要加载多个模块,因此动态加载一个模块是有意义的。
并且 (2) 我远不是导入模块和包的专家,但我通常能够让它做我想做的事。
话虽如此,如果您认为动态导入模块是您想要的,那么这应该适合您。请注意,我试图为您创建一个完整的示例:
import importlib
files = [
{"path" : "tools.tool_1", "name" : "tools__tool_1"},
{"path" : "tools.tool_2", "name" : "tools__tool_2"},
{"path" : "tools.tool_3", "name" : "tools__tool_3"}
]
module_dict = {}
main_dict = {}
for file_desc in files:
path = file_desc["path"]
name = file_desc["name"]
module = importlib.import_module(path)
module_dict[name] = module
main_dict[name] = module.main
main_dict["tools__tool_1"]()
在此示例中,三个模块都位于目录 tools
中。这些模块是 tool_1
、tool_2
和 tool_3
。它们以 tools__tool_1
等名称导入并存储在字典中。注意:您可以简单地使用 tool_1
等来表示这些名称,除非您需要使用 tools__
来限定它们因为您想将其他目录中的模块加载到相同的词典中。
请注意,这些导入中的 none 对您的全局命名空间有任何影响。模块作为对象导入,它们(或它们的 main
函数)仅存储在字典中。
关于你需要什么,我不完全确定你想要什么,所以我创建了两个词典。第一个是 module_dict
,它导入整个模块。第二个是 main_dict
,它只包含来自每个导入模块的 main
函数,如原始 post 中所述。
请注意,每个模块只导入一次。如果您只需要其中一本词典,只需删除不需要的词典即可。
无论如何,假设您想从 tools.tool_1
调用 main
。您可以从 main_dict
执行此操作,如下所示:
main_dict["tools__tool_1"]()
如果您想从 module_dict
调用它或任何其他函数,您可以这样做:
module_dict["tools__tool_1"].main()
您基本上可以从 module_dict
访问模块中的所有内容,但如果您只想访问 main
,那么您可以只使用 main_dict
.
同样,这里可能比您需要的更多,但我不完全确定您打算如何使用它。如果您只需要其中一本词典,只需去掉另一本即可。