如何使大型Python软件包模块化?

时间:2020-09-15 08:41:54

标签: python-3.x

在我的公司中,我们有一个Python项目,其中包含由我们的不同应用程序共享的许多包和模块的层次结构。但是,使代码相互融合的好主意已经变得很难使用和维护。

根据最终项目的不同,我们使用此库中的单个模块或一个或多个包。并且某些模块/程序包是独立的,但其他模块/程序包则依赖于同一库中的其他程序包/模块。当然,这些模块取决于第三方软件包。

我想使其尽可能地模块化,即我想处理以下情况:

  • 使用整个库
  • 使用该库中的单个程序包(无论它是否是顶级程序包)
  • 使用库中的单个模块
  • 使用库中的多个包/模块(可能相互依赖)

此外,我的一个强项约束是不破坏现有代码,以便我可以在不破坏我同事所有项目的情况下进行项目转换...


这是代表情况的示例文件树:

library
├── a
│   └── i
│       ├── alpha.py         # each module may depend on any other package / module
│       └── beta.py
├── b
│   ├── delta.py
│   ├── gamma.py
│   └── j
│       └── epsilon.py
├── c
│   ├── mu.py
│   └── nu.py
├── requirements.txt
└── setup.py

我发现最好的解决方案是在树的每个文件夹中添加一个setup.py和一个requirements.txt。但这有严重的局限性:

  • 我不能使用单个模块(必须使用一个包装)。
  • 使用包时,必须更改其导入语句。例如,如果在进行任何更改之前,我使用from library.a.i import alpha,那么我之后便不想对其进行修改。

此外,我很确定我会忘记我的一些限制...

那么我想实现的目标是可行的,还是乌托邦式的?

1 个答案:

答案 0 :(得分:0)

您可以执行以下操作: 您需要使PYTHONPATH指向library或将其附加到sys.path 例如sys.path.insert(0, 'path_to_libray')

如果您在文件夹的每个级别上创建__init__.py,您将可以选择感兴趣的任何级别/模块,例如:

在文件夹b中:

from .delta import *
from .gamma import *
from b.j import *

在文件夹j中:

from .epsilon import *

您现在可以在任何python脚本中进行操作:

  • from b import *:将导入所有包含的b个模块
  • from b.j import *:仅导入epsilon内容