如何使用 importlib 动态加载 python-Files?
How to load python-Files dynamcially with importlib?
我想将 .py 文件(插件)动态加载到我的程序中。
经过一些研究,我发现通常有两种方法可以做到这一点:
1)
import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
from importlib import import_module
module = import_module("plugins." + modulename)
for name, klass in inspect.getmembers(module, inspect.isclass):
if klass.__module__ == "plugins." + modulename:
instance = klass()
if isinstance(instance, IPluginTemplate):
print("Plugin Call:", instance.do_something(x))
两种解决方案的主要区别是什么?有更好的方法吗?
在第二个例子中,你运行遍历了一个模块的所有成员,这更像是一种蛮力方法。
第一个例子(第二个也是),你找不到你想要的。如果在实例化期间未找到或出错,请测试 None。
您也可以直接从 importlib 使用 import_module。这样你就可以使用 getattr return 你想从模块中得到什么,如果抛出 AttributeError return None。
您可以使用此方法 return 模块、变量以及定义到模块中的任何内容。
import importlib
def get_from_module(module, attr_name):
module = importlib.import_module(module)
try:
return getattr(module, attr_name)
except AttributeError:
return None
klass = get_from_module("plugins." + modulename, classname)
if klass is not None:
instance = klass()
这个方法在我的项目 cartola 上可用,它有一些我在多个项目中使用的轻量级 util 方法。它在 pypi 上可用,请随意从配置模块导入 get_from_module 或 get_from_string。
参见:
- https://github.com/candango/cartola/blob/develop/cartola/config.py
- https://pypi.org/project/cartola/
注意:此处的引用必须是您的 PYTHONPATH 中存在的有效模块,因为您正在处理插件。我假设是这种情况。
我想将 .py 文件(插件)动态加载到我的程序中。
经过一些研究,我发现通常有两种方法可以做到这一点:
1)
import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
from importlib import import_module
module = import_module("plugins." + modulename)
for name, klass in inspect.getmembers(module, inspect.isclass):
if klass.__module__ == "plugins." + modulename:
instance = klass()
if isinstance(instance, IPluginTemplate):
print("Plugin Call:", instance.do_something(x))
两种解决方案的主要区别是什么?有更好的方法吗?
在第二个例子中,你运行遍历了一个模块的所有成员,这更像是一种蛮力方法。
第一个例子(第二个也是),你找不到你想要的。如果在实例化期间未找到或出错,请测试 None。
您也可以直接从 importlib 使用 import_module。这样你就可以使用 getattr return 你想从模块中得到什么,如果抛出 AttributeError return None。
您可以使用此方法 return 模块、变量以及定义到模块中的任何内容。
import importlib
def get_from_module(module, attr_name):
module = importlib.import_module(module)
try:
return getattr(module, attr_name)
except AttributeError:
return None
klass = get_from_module("plugins." + modulename, classname)
if klass is not None:
instance = klass()
这个方法在我的项目 cartola 上可用,它有一些我在多个项目中使用的轻量级 util 方法。它在 pypi 上可用,请随意从配置模块导入 get_from_module 或 get_from_string。
参见:
- https://github.com/candango/cartola/blob/develop/cartola/config.py
- https://pypi.org/project/cartola/
注意:此处的引用必须是您的 PYTHONPATH 中存在的有效模块,因为您正在处理插件。我假设是这种情况。