【问题标题】:How to properly organize a package/module dependency tree?如何正确组织包/模块依赖树?
【发布时间】:2009-02-09 12:19:02
【问题描述】:

早上好,

我目前正在编写一个 python 库。目前,模块和类以无组织的方式部署,没有合理的设计。随着我接近更正式的版本,我想重新组织类和模块,以便它们具有更好的整体设计。我画了一个导入依赖关系图,我打算按层级聚合类。另外,我正在考虑对类进行一些修改,以减少这些依赖关系。

对于一个潜在复杂且正在开发中的 Python 库进行良好的整体设计,您的策略是什么?你有什么有趣的建议吗?

谢谢

更新:

我确实在寻找经验法则。例如,假设发生这种情况(init.py 为清楚起见已删除)

foo/bar/a.py
foo/bar/b.py
foo/hello/c.py
foo/hello/d.py

现在,如果你碰巧有 d.py 导入 bar.b 和 a.py 导入 hello.c,我会认为这是一个糟糕的设置。另一种情况是

foo/bar/a.py
foo/bar/baz/b.py
foo/bar/baz/c.py

假设 a.py 和 b.py 都导入 c。你有三个解决方案: 1) b 导入 c,a 导入 baz.c 2) 你在 foo/bar 中移动 c。 a.py 导入 c,b.py 导入 .c 3)你把c移到别的地方(比如foo/cpackage/c.py),然后a和b都导入cpackage.c

我倾向于选择 3),但是如果 c.py 作为独立模块没有意义,例如因为你想将它“私有”到 bar 包中,我会优先选择 1)。

还有很多类似的案例。我的经验法则是至少减少依赖和交叉的数量,以防止高度分支、高度交织的设置,但我可能是错的。

【问题讨论】:

    标签: python


    【解决方案1】:

    “我画了一个导入依赖关系图,我打算按层级聚合类。”

    Python 必须像英语(或任何其他自然语言)一样阅读。

    import 是一流的语句,应该具有真正的意义。按“层级”(无论是什么)组织事物应该清晰、有意义且显而易见。

    不要将类的任意技术组合成模块,将模块组合成包。

    使模块和包明显且合乎逻辑,以便导入列表明显、简单且合乎逻辑。

    “另外,我正在考虑对类进行一些修改,以减少这些依赖关系。”

    减少依赖听起来技术性和随意性。可能不是,但听起来是这样。没有实际的例子是不可能的。

    您的目标是清晰。

    此外,模块和包是独立的重用单元。 (不是类;一个类,但它本身通常不能重用。)您的依赖关系树应该反映这一点。您的目标是可以整齐干净地导入您的应用程序的模块。

    如果您有许多密切相关的模块(或替代实现),则可以使用包,但要谨慎使用。 Python 库相对扁平;并且其中有一些智慧。


    编辑

    层之间的单向依赖是一个基本特征。这更多是关于正确的软件设计,而不是关于 Python。您应该 (1) 分层设计,(2) 设计使层之间的依赖关系非常严格,然后 (3) 在 Python 中实现它。

    这些包不一定完全适合您的分层。这些包在物理上可能是一个平面目录列表,其依赖关系仅通过import 语句表示。

    【讨论】:

    • 对于层,我的意思是组织我的包,以便它们的类/模块依赖于该包的东西,或者另一个包含“较低”服务的东西。我会将每个包视为一个“独立库”,最终取决于其他包,因此不会有循环依赖。
    【解决方案2】:

    这个问题很模糊。

    您可以通过从库的其余部分不导入任何内容的基本/核心内容以及从此处导入的具体实现来实现此目的。除了“在导入时没有两个模块相互导入”之外,你应该没问题。

    module1.py:

    import module2
    

    module2.py:

    import module1
    

    这行不通!

    【讨论】:

    • 实际上,您的示例原样 /would/ 工作。我不会投反对票,因为您的方法是一个很好的经验法则:不要有两个模块相互导入,如果有,请修复您的设计。
    【解决方案3】:

    这取决于项目,对吧? 例如,如果您使用的是模型-视图-控制器设计,那么您的包的结构会使得 3 组代码独立。

    如果您需要一些想法,请打开您的站点包目录,并查看这些模块中的一些代码以了解它们是如何设置的。

    不了解模块就没有正确的方法;正如阿里所说,这是一个模糊的问题。你真的只需要分析你面前的东西,并找出可能更好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      相关资源
      最近更新 更多