【发布时间】:2020-03-16 06:35:18
【问题描述】:
没有快速的方法来描述这个问题,所以请跟我来! A similar question was already asked,但我的用例有点不同。解释它的最简单方法是描述一个实际用例:
我有一个文件夹,其中包含一些常用实用程序模块,我的脚本正在使用这些模块。
commonPythonFiles/
pathUtils.py
procUtils.py
specialModuleUtils.py
groupedCommonPythonFiles/
groupUtils1.py
groupUtils2.py (*)
这些模块可能有交叉导入:procUtils 使用来自pathUtils.py 的函数,而groupUtils1.py 使用它们两者(procUtils.py 和pathUtils.py)。
有一个特殊的模块,它在脚本开始时不可用 - 它是在 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.py 在 import 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()
这会使函数杂乱无章,重复导入语句并使常用实用程序模块的使用变得复杂。
- 将特殊模块生成作为脚本的先决条件 -
main.py应该在已经准备好的环境中运行,并且可以导入specialModule.py。 这意味着,在执行任何脚本之前,需要运行一些其他脚本/作业/进程来准备specialModule.py另外,这个脚本也会限制使用常见的python文件,否则它可能会像main.py一样失败。
由于提取此特殊模块 (args = groupUtils1.getSpecialModuleArguments(sys.argv)) 需要一些逻辑,因此不能选择简单的虚拟环境(或者是吗?)。
问:我真正遇到的问题是:处理导入的正确方法是什么,或者一般来说,对于这种非标准情况,最好的模块层次结构是什么?
【问题讨论】:
-
如何重新评估您的整个设计,以便您在其中一个可以填充的模块中拥有一个普通的 dict,而不是“特殊模块”?无论如何,模块基本上只是一个共享命名空间字典......
-
也许重新设计会让你摆脱交叉导入。
-
有许多“通用”文件,因为这允许我们将功能打包到模块中,按功能分组。这样代码就不会重复,这是通用文件的基本思想。 'specialModule'其实也是某种通用文件,但是是版本化的(一些较大软件的python SDK API)-意思是,它通常是从特定路径动态导入的。问题是,添加这个路径很不方便并在某些脚本的最开始处实际动态导入此模块。
标签: python python-3.x hierarchy software-design python-module