【问题标题】:How to load python-Files dynamcially with importlib?如何使用 importlib 动态加载 python-File?
【发布时间】:2021-10-20 14:59:45
【问题描述】:

我想将 .py-Files(插件)动态加载到我的程序中。

在做了一些研究之后,我发现通常有两种方法:

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))

这两种解决方案的主要区别是什么?有没有首选的方法?

【问题讨论】:

    标签: python python-importlib


    【解决方案1】:

    在第二个示例中,您正在运行模块的所有成员,这更像是一种蛮力方法。

    第一个例子(第二个也是),你找不到你想要的。如果未找到或在实例化过程中出现错误,则测试 None。

    您也可以直接从 importlib 使用 import_module。这样,您可以使用 getattr 从模块中返回您想要的内容,如果抛出 AttributeError 则返回 None。

    您可以使用此方法返回模块、变量以及定义到模块中的任何内容。

    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。

    见:

    注意:这里的引用必须是 PYTHONPATH 中存在的有效模块,因为您正在处理插件。我假设是这种情况。

    【讨论】:

      猜你喜欢
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 2010-10-07
      • 2021-12-03
      相关资源
      最近更新 更多