【发布时间】: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 并提高水平可能会解决它。