directory-structure - Python应用程序的最好的项目结构是什么?

  显示原文与译文双语对照的内容

假设你希望开发一个 non-trivial python 终端用户桌面( 不是站点) 应用程序。 构造项目层次结构文件夹的最佳方式是什么?

理想的特性是易于维护,IDE-friendliness,源代码管理分支/合并的适用性,以及易于生成的软件包。

特别是:

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

没有太多的事情。不管什么让你高兴都会工作。 没有很多愚蠢的规则,因为 python 项目很简单。

  • /scripts 或者 /bin 用于那种command-line接口
  • /tests 用于你的测试
  • /lib 用于你的C-language库
  • /doc 用于大多数文档
  • /apidoc 用于 Epydoc-generated API文档。

top-level目录可以包含,自述文件和配置。

困难的选择是是否使用 /src 树。 python 没有像Java或者C 那样的/src/lib/bin 之间的区别。

由于 top-level /src 目录被认为是无意义的,你的top-level目录可以是应用程序的top-level架构。

  • /foo
  • /bar
  • /baz

我建议把所有这些放在"name-of-my-product"目录下。 所以,如果你正在编写一个名为 quux的应用程序,那么包含所有这些内容的目录就是 /quux

另一个项目 PYTHONPATH,那么可以包含 /path/to/quux/foo 来重用 QUUX.foo 模块。

对于我来说,因为我使用科莫多编辑,我的idecuft单个. KPF 文件。 我实际上把它放在 top-level /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通常在自由节点 #python 给出答案。

文件系统 python 项目的结构

执行:

  • 命名与你的项目相关的目录。 例如如果你的项目名为"Twisted",则为它的源文件命名为top-level目录 Twisted 。 当你发布时,应该包含版本号后缀: Twisted-2.5
  • 创建一个目录 Twisted/bin 并将你的可执行文件放在那里,如果你有任何。 不给他们一个 .py 扩展,即使它们是 python 源文件。 不要将任何代码放入其中,除非导入和调用在你的项目中定义的主函数。 ( 轻微皱纹:在 Windows 上,解释器是由文件扩展名选择的,你的Windows 用户实际上想要. py 扩展。 因此,当你为 Windows 打包时,你可能想要添加它。 不幸的是,我不知道如何让这个过程自动化。 考虑到在POSIX上,. py 扩展是一个惟一的缺点,而在 Windows 上,缺少的是一个实际的Bug,如果你的userbase包含 Windows 用户,那么你可能想要选择. py 扩展。)
  • 如果你的项目是作为单个 python expressable源文件,然后把它放到目录和名称与你的项目相关的东西。 例如 Twisted/twisted.py 。如果你需要多个源文件,请创建一个软件包,并将源文件放入其中。 例如 Twisted/twisted/internet.py
  • 把你的单元测试的sub-package ( 注意:这意味着单一 python 源文件选项上面是一个技巧——你总是需要至少一个其他文件为你的单元测试) 你的包。 例如 Twisted/twisted/test/ 。当然,让它成为一个带有 Twisted/twisted/test/__init__.py的包。 将测试放在文件中 Twisted/twisted/test/test_internet.py
  • 添加 Twisted/READMETwisted/setup.py 来解释并安装你的软件,如果你觉得不错的话。

不要:

  • 将你的源放在一个名为 src 或者 lib的目录中。 这使得没有安装就很难运行。
  • 将测试放在 python 软件包之外。 这使得对已经安装版本运行测试变得困难。
  • 创建一个包,只有__init__.py 然后把所有代码放进 __init__.py 。 只是做一个模块而不是一个包,它更简单。
  • 试图让 python 能够导入你的模块或者包,而不让用户将包含它的目录添加到导入路径( 或者通过PYTHONPATH或者其他的机制) 。 你不将正确处理所有情况下,用户会生气你当你的软件并不在他们的环境中工作。

签出打开 python 项目右键单击项目。

让我来摘录一下的项目布局 。

当设置一个项目时,( 或者目录结构)的布局是很重要的。 合理的布局意味着潜在的贡献者不必花费大量的时间去寻找一段代码;文件位置是直观的。 因为我们正在处理一个现有项目,这意味着你可能需要移动一些东西。

让我们从头开始。 大多数项目有许多top-level文件( 像 setup.py, README.md,requirements.txt, 等) 。 然后,每个项目都应该有三个目录:

  • 包含项目文档的文档目录
  • 名为项目名称的目录,它存储实际的python 包
  • 在两个位置中的一个测试目录
    • 在包含测试代码和资源的软件包目录下
    • 作为一个独立的顶级目录,可以更好地了解你的文件如何组织,下面是一个对我的项目的布局的简化快照,sandman:

$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
| |-- conf.py
| |-- generated
| |-- index.rst
| |-- installation.rst
| |-- modules.rst
| |-- quickstart.rst
| |-- sandman.rst
|- requirements.txt
|- sandman
| |-- __init__.py
| |-- exception.py
| |-- model.py
| |-- sandman.py
| |-- test
| |-- models.py
| |-- test_sandman.py
|- setup.py

你可以看到,有一些顶级文件,一个文档目录( 生成的是一个空目录,sphinx将在其中放置生成的文档),一个sandman目录和一个在sandman下的测试目录。

值得阅读的是关于打包的python 文档。

http://docs.python.org/tutorial/modules.html#packages

同时确保你熟悉该页面上的其他信息。

以我的经验,这只是一个迭代。 把你的数据和代码放在你认为他们去的地方。 你可能会出错的。 但是一旦你更好地了解了事情将如何形成,你就能更好地做出这些猜测。

对于扩展源,我们在trunk下面有一个代码目录,它包含 python 目录和其他各种语言的目录。 就个人而言,我更倾向于将任何扩展代码放在它自己的仓库中,下次就会。

这样的话,我回到起点: 不要把太大的事情做出来。 把它放在似乎适合你的地方。 如果你发现一些无法工作的东西,它可以被改变。

尝试使用 python_boilerplate 模板启动项目。 它主要遵循最佳实践( 例如。 在这里,但更适合你,你发现你愿意把你的项目分割成一个上的蛋( 并且相信我,除了最简单的项目,你将会看到你自己) 。 一个常见的情况是,你必须使用别人的locally-modified版本的库。

  • 你把源放在哪里?

    • 对于体面的大型项目来说,把源分成几个鸡蛋是有意义的。 每个鸡蛋会作为一个单独的setuptools-layout PROJECT_ROOT/src/<egg_name> 之下。
  • 你将应用程序启动脚本放在哪里?

    • 理想的选择是让应用程序启动脚本在一个egg中注册为 entry_point
  • 你把IDE项目放在什么地方了?

    • 依赖 IDE 。其中很多都将它们的内容保存在项目根中,这很好。
  • 将单元/验收测试放在哪里?

    • 每个蛋都有一组单独的测试,保存在它 PROJECT_ROOT/src/<egg_name>/tests 目录。我个人喜欢使用 py.test 来运行它们。
  • 哪里你把non-Python等数据配置文件?

    • 这取决于non-Python数据的不同类型。
      • "资源",换句话说,数据,必须打包在egg中。 这些数据进入相应的egg目录,位于包命名空间的某处。 它可以通过 pkg_resources 软件包使用。
      • "config-files",换句话说,non-Python文件,将被视为项目源文件外部的文件,但当应用程序开始运行时必须用一些值初始化。 开发过程中,我喜欢将这些文件保存在 PROJECT_ROOT/config 中。 对于部署,可以有多种选项。 在 Windows 上,可以使用 %APP_DATA%/<app-name>/config,在 Linux,/etc/<app-name> 或者 /opt/<app-name>/config 上。
      • 生成的文件,换句话说,文件,可以在执行过程中由应用程序创建或者修改。 我宁愿在开发期间将它们保留在 PROJECT_ROOT/var 中,在Linux部署期间将它们放在 /var 中。
  • 哪里你把non-Python来源如 C++ pyd/二进制扩展模块呢?
    • 进入 PROJECT_ROOT/src/<egg_name>/native

文档通常会进入 PROJECT_ROOT/doc 或者 PROJECT_ROOT/src/<egg_name>/doc ( 这取决于你是否将一些鸡蛋视为一个单独的大型项目) 。 一些额外的配置将在像 PROJECT_ROOT/buildout.cfgPROJECT_ROOT/setup.cfg 这样的文件中。

Non-python数据最好是捆绑在你 python 模块使用 package_data 支持 setuptools 。 我强烈推荐的一件事是使用名称空间包来创建共享名称空间多个项目可以使用--就像java的把包放在 com.yourcompany.yourproject ( 并且能够拥有一个共享的com.yourcompany.utils 命名空间) 。

分支和合并,如果你使用一个足够好的源代码控制系统通过重命名它甚至将处理合并; Bazaar 尤其擅长这个。

这里的其他问题相反,我是 +1的src 目录 top-level ( 同时使用 doctest 目录) 。 文档目录树的具体约定将取决于你使用的是什么; Sphinx,例如,有自己的约定其快速入门工具支持。

请使用setuptools和 pkg_resources ;这使得其他项目更容易依赖于代码( 和与不同的non-code文件同时安装多个版本,如果你使用的是 package_data )的特定版本。

...