协慌网

登录 贡献 社区

Python 应用程序的最佳项目结构是什么?

想象一下,您想用 Python 开发非平凡的最终用户桌面(非 Web)应用程序。构造项目文件夹层次结构的最佳方法是什么?

理想的功能是易于维护,IDE 友好,适用于源代码控制分支 / 合并以及易于生成安装软件包。

特别是:

  1. 您将源放在哪里?
  2. 您将应用程序启动脚本放在哪里?
  3. 您将 IDE 项目放在哪里?
  4. 您将单元 / 验收测试放在哪里?
  5. 您将非 Python 数据(例如配置文件)放在哪里?
  6. 您在哪里将非 Python 来源(例如 C ++)用于 pyd / so 二进制扩展模块?

答案

没什么大不了的。令您快乐的一切都会起作用。没有很多愚蠢的规则,因为 Python 项目可以很简单。

  • /scripts/bin用于那种命令行界面
  • /tests为您的测试
  • /lib用于您的 C 语言库
  • /doc获取大多数文档
  • /apidoc用于 Epydoc 生成的 API 文档。

顶级目录可以包含自述文件,配置文件和其他内容。

艰难的选择是是否使用/src树。像 Java 或 C 一样, /src/lib /bin之间没有区别。

由于/src目录没有意义,因此顶级目录可以是应用程序的顶级体系结构。

  • /foo
  • /bar
  • /baz

我建议将所有这些都放在 “我的产品名称” 目录下。因此,如果您正在编写一个名为quux的应用程序,则包含所有这些内容的目录将命名为/quux

然后,另一个项目的PYTHONPATH /path/to/quux/foo以重用QUUX.foo模块。

就我而言,由于我使用 Komodo Edit,因此我的 IDE cuft 是单个. KPF 文件。我实际上将其放在顶层/quux目录中,并省略了将其添加到 SVN 中的情况。

根据 Jean-Paul Calderone 的Python 项目的文件系统结构

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README

Jean-Paul Calderone 的这篇博客文章通常在 Freenode 上的 #python 中作为答案给出。

Python 项目的文件系统结构

做:

  • 为目录命名与您的项目相关的名称。例如,如果您的项目名为 “Twisted”,则将其源文件Twisted命名为顶级目录。发布时,应包括版本号后缀: Twisted-2.5
  • 创建目录Twisted/bin并将可执行文件放在此处(如果有)。即使它们是 Python 源文件,也不要给它们添加.py除了在项目中其他位置定义的 main 函数的导入和调用外,不要在其中添加任何代码。 (略有起皱:由于在 Windows 上,解释器是由文件扩展名选择的,因此 Windows 用户实际上确实需要. py 扩展名。因此,在为 Windows 打包时,您可能希望添加它。不幸的是,没有简单的 distutils 技巧可以考虑到在 POSIX 上. py 扩展名只是一个疣,而在 Windows 上缺少是一个实际的错误,如果您的用户群包括 Windows 用户,则可能希望仅使用. py。扩展到处。)
  • 如果您的项目可表示为单个 Python 源文件,则将其放入目录并命名与您的项目相关的名称。例如, Twisted/twisted.py 。如果需要多个源文件,请创建一个包( Twisted/twisted/ ,其中包含一个空的Twisted/twisted/__init__.py ),然后将源文件放入其中。例如, Twisted/twisted/internet.py
  • 将单元测试放在程序包的子包中(请注意 - 这意味着上面的单个 Python 源文件选项是一个技巧 -单元测试总是需要至少一个其他文件)。例如, Twisted/twisted/test/Twisted/twisted/test/__init__.py使其成为一个包。将测试放置在Twisted/twisted/test/test_internet.py
  • 如果感觉不错,分别添加Twisted/READMETwisted/setup.py来解释和安装软件。

别:

  • 将您的源代码放在名为srclib的目录中。这使得不安装就很难运行。
  • 将测试放到 Python 包之外。这使得很难针对已安装的版本运行测试。
  • 创建一个仅包含__init__.py的包,然后将所有代码放入__init__.py 。只需制作一个模块而不是一个包,就更简单了。
  • 尝试提出一些神奇的技巧,以使 Python 能够导入您的模块或包,而无需用户将包含它的目录添加到其导入路径(通过 PYTHONPATH 或其他机制)。您将无法正确处理所有情况,并且当您的软件无法在其环境中运行时,用户会为您生气。