python 动态加载模块

动态加载模块在插件化中很重要,但是在agent 周边也是比较重要的,比如我们基于ai 生成代码,同时需要动态加载执行代码模块,python 内置了不少方法以下简单说明下

通过importlib.import_module

注意此模式会加载到sys.modules 中,会有cache的问题,同时会有sys.path 查找的问题,可以通过importlib.reload 进行重新加载reload

  • 参考玩法
module = importlib.import_module(f"mymodules_{runner_id}.app")
importlib.reload(module)

通过importlib.util.spec_from_file_location

此模式就比较自由了,路径可以自己指定,每次都是新的module,同时不会cache 到sys.modules中

  • 参考玩法
spec = importlib.util.spec_from_file_location(module_name, path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

说明

以上是动态加载的方法,使用好了价值还是比较大的,但是注意动态加载是不进行隔离的,实现加载模块以及依赖(通过uv ),可以参考如下

  • importlib.util.spec_from_file_location 模式
def load_module_from_path(module_name, path):
    try:
        spec = importlib.util.spec_from_file_location(module_name, path)
        module = importlib.util.module_from_spec(spec)
        # install dependencies if requirements.txt exists
        requirements_path = os.path.join(os.path.dirname(path), "requirements.txt")
        if os.path.exists(requirements_path):
            import subprocess
            subprocess.check_call(["uv", "pip", "install", "-r", requirements_path])
        spec.loader.exec_module(module)
        return module
    except ModuleNotFoundError as e:
        print(f"Error loading module {module_name} from path {path}: {e}")
       
  • importlib.import_module
def get_module_dir(module_name):
    spec = importlib.util.find_spec(module_name)
    if spec is None:
        raise ModuleNotFoundError(module_name)

    # package
    if spec.submodule_search_locations:
        return list(spec.submodule_search_locations)[0]

    # 普通模块
    return os.path.dirname(spec.origin)

def load_module_from_module_with_cache(module_name, *args, **kwargs):
    try:
        requirements_path = os.path.join(get_module_dir(f"plugins.{module_name}"), "requirements.txt")
        if os.path.exists(requirements_path):
            import subprocess
            subprocess.check_call(["uv", "pip", "install", "-r", requirements_path])
        return importlib.import_module(f"plugins.{module_name}.app")
    except ModuleNotFoundError:
        print(f"Module plugins.{module_name} not found, loading from path")
        raise ModuleNotFoundError(f"Module plugins.{module_name} not found, loading from path")

参考资料

https://docs.python.org/3/library/importlib.html

https://docs.python.org/3/library/importlib.html#module-importlib.util

posted on 2026-04-07 08:00  荣锋亮  阅读(15)  评论(0)    收藏  举报

导航