Python:模块导入层次结构(启动时不存在的模块)

Python: module import hierarchy (non-existing modules at startup)

没有快速描述这个问题的方法,请继续关注我! A similar question was already asked,但我的用例有点不同。最简单的解释方法是描述一个实际用例:

我有一个包含一些常用实用程序模块的文件夹,我的脚本正在使用这些模块。

commonPythonFiles/
    pathUtils.py
    procUtils.py
    specialModuleUtils.py

    groupedCommonPythonFiles/
        groupUtils1.py
        groupUtils2.py (*)

此模块可能有交叉导入:procUtils 使用来自 pathUtils.py 的函数,而 groupUtils1.py 使用它们(procUtils.pypathUtils.py)。

有一个特殊的模块,从脚本开始时不可用 - 它是 extracted/copied/generated/... 在 main.py 的 运行 时间通过使用specialModuleUtils.py 个函数。

specialModuleFolder/ # not available from the start
    specialModule.py

另一方面,groupUtils2.py (*) 是这样的 specialModule.py 的包装。

在某些工作脚本中(例如,main.py),需要此实用程序模块,因此,它们通常在文件的开头导入。


问题

#main.py
import pathUtils
import procUtils
import specialModuleUtils
import groupUtils1
import groupUtils2 # (!)

def main():
    # prepare special module
    args = groupUtils1.getSpecialModuleArguments(sys.argv) # might be a lot more than one line to get arguments
    specialModuleUtils.create(args)

    # do some stuff with groupUtils2 which use created special module
    groupUtils2.doSomeStuffWithSpecialModule()

您可能已经怀疑我面临的问题。我正在导入尚不可用的模块。 main.pyimport groupUtils2 处失败,因为尚未创建 specialModuleUtils

我真正纠结的问题是:处理导入的正确方法是什么,或者一般来说,对于这种非标准情况,最好的模块层次结构是什么?


可能的解决方案

#main.py
import pathUtils
import procUtils

def main():
    import groupUtils1
    import specialModuleUtils
    # prepare special module
    args = groupUtils1.getSpecialModuleArguments(sys.argv) # might be a lot more than one line to get arguments
    specialModuleUtils.extract(args)

    # do some stuff with groupUtils2 which use created special module
    import groupUtils2
    groupUtils2.doSomeStuffWithSpecialModule()

这会使函数混乱、重复导入语句并使通用实用程序模块的使用复杂化。

由于需要一些逻辑来提取这个特殊模块 (args = groupUtils1.getSpecialModuleArguments(sys.argv)),简单的虚拟环境不是一个选项(或者是吗?)。

Q:我真正纠结的问题是:处理导入的正确方法是什么,或者一般来说,这种非标准的最佳模块层次结构是什么案例?

当然只有生成的文件的导入必须延迟,或者通过 groupUtils2 仅在其函数内部导入它(或者作为 分配的显式初始化步骤 使用 global) 导入的模块,或者通过在 main 中导入(仅)groupUtils2 一旦它对 specialModule 的热切导入成功。这些都不是深刻的重组。