Python应用程序的最佳项目结构是什么?
假设你想用Python开发一个比较复杂的桌面应用程序(不是网页应用)。那么,项目的文件夹结构应该怎么安排才好呢?
理想的情况是,这个结构要容易维护,适合在开发环境中使用,还要方便进行版本控制的分支和合并,同时也要能轻松生成安装包。
具体来说:
- 源代码应该放在哪里?
- 应用程序的启动脚本放在哪儿?
- 开发环境的项目文件放在哪儿?
- 单元测试和验收测试放在哪里?
- 非Python的数据,比如配置文件,放在哪儿?
- 非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/README
和Twisted/setup.py
来解释和安装你的软件。不应该做的:
- 不要把源代码放在叫
src
或lib
的文件夹里。这会让运行起来变得困难。- 不要把测试放在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中。