用相对导入动态导入模块的正确方法? [英] Proper way to dynamically import a module with relative imports?

查看:154
本文介绍了用相对导入动态导入模块的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



结构如下:

  project_folder / 
project /
__init__.py
__main__.py
plugins /
__init__.py
plugin1 /
__init__.py
...
plugin2 /
__init__.py
...

我做了这个函数加载一个模块:

  import os 

from importlib.util import spec_from_file_location,module_from_spec


def load_module(path,name =):
通过路径加载模块$
try:
name = name if name!=else path.split(os.sep)[ - 1]#取默认的模块名称
spec = spec_from_file_location name,os.path.join(path,__init__.py))
plugin_module = module_from_spec(spec)
spec.loader.exec_module(plugin_module)
return plugin_module
除了例外为e:
print(加载模块失败,路径, - >,e)

它可以工作,除非模块使用相对导入:


未加载模块/路径/ to / plugins / plugin1 - >父模块'plugin1'未加载,无法执行相对导入


我做错了什么?

解决方案

我设法解决了自己的问题,经过大量的搜索。原来我需要使用相对路径导入:

 >>>来自importlib import import_module 
>>>> config = import_module(plugins.config)
>>> config
< module'plugins.config'from'/path/to/plugins/config/__init__.py'>
>>>


I need to dynamically import modules into my project from another package.

The structure is like:

project_folder/
    project/
        __init__.py
        __main__.py
    plugins/
        __init__.py
        plugin1/
            __init__.py
            ...
        plugin2/
            __init__.py
            ...

I made this function to load a module:

import os

from importlib.util import spec_from_file_location, module_from_spec


def load_module(path, name=""):
    """ loads a module by path """
    try:
        name = name if name != "" else path.split(os.sep)[-1]  # take the module name by default
        spec = spec_from_file_location(name, os.path.join(path, "__init__.py"))
        plugin_module = module_from_spec(spec)
        spec.loader.exec_module(plugin_module)
        return plugin_module
    except Exception as e:
        print("failed to load module", path, "-->", e)

It works, unless the module uses relative imports:

failed to load module /path/to/plugins/plugin1 --> Parent module 'plugin1' not loaded, cannot perform relative import

What am I doing wrong?

解决方案

I managed to solve my own issue after a LOT of googling. Turns out I needed to import using relative paths:

>>> from importlib import import_module
>>> config = import_module("plugins.config")
>>> config
<module 'plugins.config' from '/path/to/plugins/config/__init__.py'>
>>> 

这篇关于用相对导入动态导入模块的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆