假设您想要用Python开发一个重要的终端用户桌面(而不是web)应用程序。构建项目文件夹层次结构的最佳方法是什么?

理想的特性是易于维护、ide友好性、适合源代码控制分支/合并,以及易于生成安装包。

特别是:

你把源头放在哪里? 应用程序启动脚本放在哪里? 你把IDE项目的cruft放在哪里? 你把单元/验收测试放在哪里? 你把非python数据放在哪里,比如配置文件? 你把非python源代码放在哪里,比如pyd/二进制扩展模块的c++ ?


当前回答

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

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

其他回答

不太重要。只要能让你开心就行。没有很多愚蠢的规则,因为Python项目可以很简单。

/scripts或/bin之类的命令行界面 /测试你的测试 /lib为您的c语言库 /doc用于大多数文档 /apidoc用于epydoc生成的API文档。

顶层目录可以包含README, Config等等。

困难的选择是是否使用/src树。Python不像Java或C那样区分/src、/lib和/bin。

由于一些人认为顶级/src目录没有意义,所以顶级目录可以是应用程序的顶级体系结构。

/ foo /酒吧 /巴兹

我建议把所有这些都放在“我的产品名称”目录下。如果你写一个名为quux的应用程序,包含这些东西的目录就叫做/quux。

然后,另一个项目的PYTHONPATH可以包含/path/to/quux/foo来重用quux。foo模块。

在我的例子中,因为我使用Komodo Edit,所以我的IDE cuft是一个. kpf文件。实际上,我将其放在顶级/quux目录中,并忽略将其添加到SVN。

尝试使用python_boilerplate模板启动项目。它在很大程度上遵循了最佳实践(例如这里的那些),但如果你发现自己愿意在某个时候把项目分成多个鸡蛋(相信我,除了最简单的项目,你会这样做),它更适合你。一种常见的情况是,您必须使用别人库的本地修改版本)。

Where do you put the source? For decently large projects it makes sense to split the source into several eggs. Each egg would go as a separate setuptools-layout under PROJECT_ROOT/src/<egg_name>. Where do you put application startup scripts? The ideal option is to have application startup script registered as an entry_point in one of the eggs. Where do you put the IDE project cruft? Depends on the IDE. Many of them keep their stuff in PROJECT_ROOT/.<something> in the root of the project, and this is fine. Where do you put the unit/acceptance tests? Each egg has a separate set of tests, kept in its PROJECT_ROOT/src/<egg_name>/tests directory. I personally prefer to use py.test to run them. Where do you put non-Python data such as config files? It depends. There can be different types of non-Python data. "Resources", i.e. data that must be packaged within an egg. This data goes into the corresponding egg directory, somewhere within package namespace. It can be used via the pkg_resources package from setuptools, or since Python 3.7 via the importlib.resources module from the standard library. "Config-files", i.e. non-Python files that are to be regarded as external to the project source files, but have to be initialized with some values when application starts running. During development I prefer to keep such files in PROJECT_ROOT/config. For deployment there can be various options. On Windows one can use %APP_DATA%/<app-name>/config, on Linux, /etc/<app-name> or /opt/<app-name>/config. Generated files, i.e. files that may be created or modified by the application during execution. I would prefer to keep them in PROJECT_ROOT/var during development, and under /var during Linux deployment. Where do you put non-Python sources such as C++ for pyd/so binary extension modules? Into PROJECT_ROOT/src/<egg_name>/native

文档通常会进入PROJECT_ROOT/doc或PROJECT_ROOT/src/<egg_name>/doc(这取决于您是否将某些eggs视为单独的大型项目)。一些额外的配置将在PROJECT_ROOT/build - out.cfg和PROJECT_ROOT/setup.cfg这样的文件中。

非Python数据最好使用setuptools中的package_data支持绑定到Python模块中。我强烈推荐的一件事是使用名称空间包来创建多个项目可以使用的共享名称空间——很像将包放在com.yourcompany.yourproject中的Java约定(并且能够拥有一个共享的com.yourcompany.utils名称空间)。

再分支和合并,如果你使用一个足够好的源代码控制系统,它甚至可以通过重命名来处理合并;芭莎在这方面尤其在行。

与这里的其他一些答案相反,我赞成将src目录作为顶级目录(附带doc和test目录)。文档目录树的特定约定将根据您使用的内容而有所不同;例如,Sphinx有自己的快速入门工具支持的约定。

请,请利用setuptools和pkg_resources;这使得其他项目更容易依赖于您代码的特定版本(如果使用package_data,则可以使用不同的非代码文件同时安装多个版本)。

“Python打包权威”有一个样本项目:

https://github.com/pypa/sampleproject

它是一个示例项目,作为Python打包用户指南的打包和分发项目教程的辅助而存在。

这篇由Jean-Paul Calderone撰写的博客文章通常是Freenode上#python的答案。

Filesystem structure of a Python project Do: name the directory something related to your project. For example, if your project is named "Twisted", name the top-level directory for its source files Twisted. When you do releases, you should include a version number suffix: Twisted-2.5. create a directory Twisted/bin and put your executables there, if you have any. Don't give them a .py extension, even if they are Python source files. Don't put any code in them except an import of and call to a main function defined somewhere else in your projects. (Slight wrinkle: since on Windows, the interpreter is selected by the file extension, your Windows users actually do want the .py extension. So, when you package for Windows, you may want to add it. Unfortunately there's no easy distutils trick that I know of to automate this process. Considering that on POSIX the .py extension is a only a wart, whereas on Windows the lack is an actual bug, if your userbase includes Windows users, you may want to opt to just have the .py extension everywhere.) If your project is expressable as a single Python source file, then put it into the directory and name it something related to your project. For example, Twisted/twisted.py. If you need multiple source files, create a package instead (Twisted/twisted/, with an empty Twisted/twisted/__init__.py) and place your source files in it. For example, Twisted/twisted/internet.py. put your unit tests in a sub-package of your package (note - this means that the single Python source file option above was a trick - you always need at least one other file for your unit tests). For example, Twisted/twisted/test/. Of course, make it a package with Twisted/twisted/test/__init__.py. Place tests in files like Twisted/twisted/test/test_internet.py. add Twisted/README and Twisted/setup.py to explain and install your software, respectively, if you're feeling nice. Don't: put your source in a directory called src or lib. This makes it hard to run without installing. put your tests outside of your Python package. This makes it hard to run the tests against an installed version. create a package that only has a __init__.py and then put all your code into __init__.py. Just make a module instead of a package, it's simpler. try to come up with magical hacks to make Python able to import your module or package without having the user add the directory containing it to their import path (either via PYTHONPATH or some other mechanism). You will not correctly handle all cases and users will get angry at you when your software doesn't work in their environment.