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

961 投票
8 回答
704312 浏览
提问于 2025-04-11 09:32

假设你想用Python开发一个比较复杂的桌面应用程序(不是网页应用)。那么,项目的文件夹结构应该怎么安排才好呢?

理想的情况是,这个结构要容易维护,适合在开发环境中使用,还要方便进行版本控制的分支和合并,同时也要能轻松生成安装包。

具体来说:

  1. 源代码应该放在哪里?
  2. 应用程序的启动脚本放在哪儿?
  3. 开发环境的项目文件放在哪儿?
  4. 单元测试和验收测试放在哪里?
  5. 非Python的数据,比如配置文件,放在哪儿?
  6. 非Python的源代码,比如用C++写的pyd/so二进制扩展模块,放在哪儿?

8 个回答

304

这篇由 Jean-Paul Calderone 写的博客文章,常常被用作在Freenode的#python频道中的回答。

Python项目的文件系统结构

应该做的:

  • 给你的项目文件夹起个和项目相关的名字。例如,如果你的项目叫“Twisted”,那么顶层文件夹就可以叫 Twisted。发布新版本时,可以在名字后面加上版本号,比如 Twisted-2.5
  • 创建一个 Twisted/bin 文件夹,把你的可执行文件放在里面。如果有的话,不要给它们加 .py 后缀,尽管它们是Python源文件。里面只放一个导入和调用其他地方定义的主函数的代码。(稍微复杂一点的是:在Windows上,文件扩展名决定了使用哪个解释器,所以Windows用户其实是希望有 .py 后缀的。因此,当你为Windows打包时,可能需要加上这个后缀。不幸的是,我不知道有什么简单的方法可以自动化这个过程。考虑到在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或其他方式)的情况下导入你的模块或包。你不会正确处理所有情况,用户会因为你的软件在他们的环境中无法正常工作而生气。
319

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

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

其实没什么太大的关系。只要让你开心的方式就可以。Python项目没有很多复杂的规则,因为它们可以很简单。

  • /scripts/bin 用来放一些命令行工具的东西
  • /tests 用来放你的测试代码
  • /lib 用来放你的C语言库
  • /doc 用来放大部分文档
  • /apidoc 用来放通过Epydoc生成的API文档。

而顶层目录可以包含一些README文件、配置文件等等。

比较难做的选择是要不要使用一个 /src 目录。Python没有像Java或C那样区分 /src/lib/bin

因为有些人觉得顶层的 /src 目录没有意义,所以你的顶层目录可以直接是你应用程序的整体结构。

  • /foo
  • /bar
  • /baz

我建议把这些都放在一个叫“我的产品名称”的目录下。所以,如果你写的应用叫 quux,那么包含这些内容的目录就叫 /quux

其他项目的 PYTHONPATH 可以包含 /path/to/quux/foo 来重用 QUUX.foo 模块。

在我的情况下,因为我使用的是Komodo Edit,我的IDE配置是一个单独的.KPF文件。我实际上把它放在顶层的 /quux 目录里,并且没有把它添加到SVN中。

撰写回答