【问题标题】:Dynamically importing module in python3 - issue在 python3 中动态导入模块 - 问题
【发布时间】:2021-11-25 16:21:35
【问题描述】:

在一个项目中,我想根据版本号动态导入正确的模块。 为此,我使用 importlib,只要包是源代码的一部分,就可以找到。

AdminApi = import_module(f"{self.version}", "AdminApi").AdminApi

文件夹结构如下:

Admin-Package / 
    - __init__.py  # Contains dynamic class loader
    - admin64/
        - __init__.py  # contains AdminApi v6.4
        - ...
    - admin65/...
        - __init__.py  # contains AdminApi v6.5
        - ...

但是,现在我发现自己需要将代码解耦到自己的包中,以便在另一个项目中重复使用。所以我把这部分源码打包了。然而,这似乎会导致与路径相关的问题。这似乎意味着 importlib 无法帮助我。

到目前为止,感谢:https://stackoverflow.com/a/54138717/5731101 我已经到了这一点:

import importlib
from pathlib import Path

path = Path(__file__).resolve().parent
script_path = os.path.join(path, version, '__init__.py')

spec = importlib.util.spec_from_file_location(f"AdminApi", script_path)
AdminApi = importlib.util.module_from_spec(spec)
spec.loader.exec_module(AdminApi)

不幸的是,spec.loader.excec_module 失败并出现错误:ModuleNotFoundError: No module named 'AdminApi' 即使该类在通过路径提供的文件中明显可用。

如果有人能帮我解决这个问题,我将不胜感激。

【问题讨论】:

  • 只是一个问题:if version == 64: import AdminApi64 等有什么问题?如果您只有几个想要处理的版本,我会发现它更具可读性,并且可以避免与 importlib 之类的东西混淆。 Ofc 如果这个动态导入是一个特性,它可能不是一个好的解决方案
  • 这是一个公平的评论,也许我过于复杂了。然而,这将是一个很棒的功能,具体取决于我们最终得到的变化量。似乎我们与之交谈的 AdminApi 似乎在每次更新时都会有一些细微的变化 - 这是每个月。
  • 很公平。如果您只需要与 one AdminApi 交谈,我只会将其称为 Admin 并每次都替换它。但是我在您的用例中使用它,您需要多个访问权限..在任何情况下,您都有一个可以正常工作的解决方案:)(顺便说一句,另一个选项可能是使用admin = __import__(f"Admin{self.version}")(如果导入允许,则相当于import f"Admin{self.version}" as admin。我不知道,但我怀疑避免 importlib 并提高水平可能会解决它。

标签: python python-importlib


【解决方案1】:

我决定尝试 importlib 工具箱中的另一个工具基于这个答案:https://stackoverflow.com/a/67692/5731101

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("AdminAPI", "/path/to/file.py").load_module()
foo.AdminAPI()

这种方法在检测类时没有问题,只需正确导入所有内容。

【讨论】:

    猜你喜欢
    • 2019-06-04
    • 2016-03-20
    • 2019-11-01
    • 1970-01-01
    • 2013-08-09
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多