Python 依据路径动态导入模块、类、函数
• 2024-08-27 • 文章类别: 后端编程语言 • 阅读量:333
在 Python 中,要导入模块,可以在模块的开始位置使用 import
,但是预先不知道需要导入什么模块时,就不能导入模块了。在这种情况下,我们需要在 Python 中动态导入模块、类、函数。动态导入模块也能满足让我们在运行时根据需要加载模块,而不是在程序开始时就进行导入。
什么是动态导入
动态导入是指在程序运行过程中根据需要加载模块、类、函数,动态导入只需提供以点分隔的模块路径的字符串。与静态导入不同,动态导入可以根据程序的状态、条件和用户输入来决定导入哪些模块,使程序更加灵活。
Python 动态导入模块(包)
Python 有多种实现实现动态导入的方法,其中最简单的一种是使用 importlib
库中的 import_module()
函数;也可以使用 importlib
库中其他函数或类。
使用 importlib.import_module
动态导入模块
如下是一个在 Python 中使用 importlib.import_module()
函数动态导入模块的示例,该函数的参数为 String:
module = importlib.import_module("django.db.utils");
使用文件路径动态导入模块
import importlib
def import_module_by_location(module_name, module_location):
"""
导入使用点分隔的路径对应的模块
"""
spec = importlib.util.spec_from_file_location(module_name, module_location)
module = importlib.util.module_from_spec(spec)
return module
# 使用定义的函数动态导入模块
module_location = "/path/to/module.py"
module_name = "mymodule"
module = import_module_by_path(module_name, module_location)
# 调用动态导入的模块的函数、类
module.fun()
module.MyClass()
解释说明:
- 使用
importlib.util.spec_from_file_location()
函数根据给定的路径创建一个ModuleSpec
对象 - 使用
importlib.util.module_from_spec()
函数根据ModuleSpec
对象导入模块
Python 动态导入类、函数
在 Python 中没有直接定义动态导入类、函数的方法,需要自定义动态导入类、函数的方法。
自定义动态导入类、函数的方法
如下给出定义的方法,你只需把代码复制到你的文件中即可使用:
import sys
from importlib import import_module
# 从 django 中复制
def import_from_string(dotted_path):
"""
导入使用点分隔的模块中的类或函数,最后的部分为类名或函数名,加载错误将抛出 ImportError
"""
try:
module_path, class_name = dotted_path.rsplit(".", 1)
except ValueError as err:
raise ImportError("%s 看起来不像是模块路径" % dotted_path) from err
try:
# 检查模块是否已经被加载并初始化.
if not (
(module := sys.modules.get(module_path))
and (spec := getattr(module, "__spec__", None))
and getattr(spec, "_initializing", False) is False
):
module = import_module(module_path)
return getattr(module, class_name)
except AttributeError as err:
raise ImportError(
'模块 "%s" 未定义 "%s" 属性/函数/类'
% (module_path, class_name)
) from err
解释说明:
- 首先根据提供的以点分隔的路径生成模块名和类名或函数名
- 检查模块是否已经被加载并初始化,如果已经加载了,无需重新加载
使用自定义函数动态导入类、函数
Python 中动态导入类和函数是一样的,因为他们可以看作是模块的属性。
如下给出一个使用自定义函数动态导入类、函数的示例:
a_fun = import_from_string("subprocess.run")
a_fun(["ls", "-l"], text=True)
a_cls = import_from_string("subprocess.Popen")
po = a_cls()
注意
在 Python 中动态导入模块可能会增加代码的可维护性和可扩展性,但也会带来一些安全风险。例如,如果用户可以输入需要导入的模块的完整路径,可能会执行恶意操作。因此在 Python 中使用动态导入时,应该谨慎处理用户输入,以防止安全漏洞。
结语
在本文中我们介绍了在 Python 中动态导入模块的两种方法,并给出了最简单的动态导入模块的方法,同时给出了动态导入类、函数的自定义函数,使用自定义函数,可以非常方便的动态导入类和函数。
0 评论