使用 Windows 和 Linux 动态导入 Python 模块

Dynamically import Python module with Windows and Linux

我正在尝试使用 importlib.

动态导入 Python 模块

我的项目是一个 Azure 函数应用程序,具有以下文件结构:

Shared_Code/
├── __init__.py
├── model.py
└── rule_engine.py

在文件 rule_engine.py 中,我正在尝试导入 model.py:

logging.info(__name__)
importlib.import_module(
    'Shared_Code.model', package=None
)

以上代码打印

__app__.Shared_Code.rule_engine.py

并在 LinuxAzure Cloud.

上正确导入模块

然而,当在 Windows 上执行完全相同的代码时,我得到一个错误,指出找不到模块 Shared_Code

然后我使用了以下

importlib.import_module(
    '__app__.Shared_Code.model', package=None
)

两者都适用,但在 运行 Azure Cloud.

上时会中断

是否有针对此问题的通用解决方案,而无需根据 OS 执行手动检查和 if 子句?

您可以尝试使用相对路径导入 model

importlib.import_module('.model', package='Shared_Code')

编辑:经过一些研究,我得出结论,这是一个 Azure 问题,而不是 Python 问题。

完整 CPython code.

中的字符串 __app__ 没有 单一 重合

但是,this azure-functions-python-worker PR __app__ top-level 模块是为绝对导入实现的。

我猜这是 azure-functions-python-worker 或您正在使用的任何 Azure 平台中的错误,它们在 Linux 和 Azure Cloud VS Windows 之间有不同的行为。

我认为你唯一能做的是:

  • 查看您的 Azure 服务中是否有一些配置,也许 Windows 默认情况下有所不同(抱歉,我不使用 Azure 平台)。
  • azure-functions-python-worker 中填写一个问题,尝试包含一个最小的可重现示例,然后看看他们的想法(也许他们有答案,也许您发现了错误)。
  • Pythonic 解决方案:在 try/except ModuleNotFoundError 中导入没有 __app__ 的模块,如果失败再次导入 __app__:
try:
    importlib.import_module(
        'Shared_Code.model', package=None
    )
except ModuleNotFoundError:
    # In Windows, __app__ is mandatory
    importlib.import_module(
        '__app__.Shared_Code.model', package=None
    )

我知道这最后一个正是您要求 而不是 做的,但是如果它是一个平台问题(我很确定它是),那么除了处理它,你无能为力。