当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Python应用程序的最佳项目结构是什么?》经验,为你挑选了8个好方法。

想象一下,您希望在Python中开发一个非平凡的最终用户桌面(而不是Web)应用程序.构建项目文件夹层次结构的最佳方法是什么?

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

特别是:

    你把源头放在哪里?

    你把应用程序启动脚本放在哪里?

    你把IDE项目放在哪里?

    你在哪里进行单位/验收测试?

    你在哪里放置非Python数据,如配置文件?

    你在哪里为pyd/so二进制扩展模块放置非Python源代码如C++?

S.Lott.. 350

没关系太重要了.无论什么让你快乐都会奏效.没有很多愚蠢的规则,因为Python项目可以很简单.

/scripts或者/bin用于那种命令行界面的东西

/tests 为了你的测试

/lib 为您的C语言库

/doc 对于大多数文档

/apidoc 对于Epydoc生成的API文档.

顶级目录可以包含README,Config和whatnot.

很难选择是否使用/src树.Python没有区别/src,/lib/bin如Java或C具有.

由于/src某些人认为顶级目录没有意义,因此您的顶级目录可以是应用程序的顶级体系结构.

/foo

/bar

/baz

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

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

在我的情况下,因为我使用Komodo Edit,我的IDE cuft是一个.KPF文件.我实际上把它放在顶级/quux目录中,并省略将其添加到SVN.



1> S.Lott..:

没关系太重要了.无论什么让你快乐都会奏效.没有很多愚蠢的规则,因为Python项目可以很简单.

/scripts或者/bin用于那种命令行界面的东西

/tests 为了你的测试

/lib 为您的C语言库

/doc 对于大多数文档

/apidoc 对于Epydoc生成的API文档.

顶级目录可以包含README,Config和whatnot.

很难选择是否使用/src树.Python没有区别/src,/lib/bin如Java或C具有.

由于/src某些人认为顶级目录没有意义,因此您的顶级目录可以是应用程序的顶级体系结构.

/foo

/bar

/baz

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

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

在我的情况下,因为我使用Komodo Edit,我的IDE cuft是一个.KPF文件.我实际上把它放在顶级/quux目录中,并省略将其添加到SVN.


我不倾向于认为Django是一个很好的例子 - 使用sys.path的技巧是我书中的即时DQ.
你建议模拟他们的目录结构的任何开源python项目?
重新"欺骗":Django将根项目文件夹的父级添加到sys.path,以便可以将模块导入为"from project.app.module import klass"或"from app.module import klass".
看看Django就是一个很好的例子.
哦,我喜欢这个技巧,现在正在使用。我想将共享模块放在另一个目录中,我不想在系统范围内安装模块,也不想让人们手动修改PYTHONPATH。除非人们提出更好的建议,否则我认为这实际上是最干净的方法。

2> cmcginty..:

根据Jean-Paul Calderone的Python项目的Filesystem结构:

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


bin文件夹中的可执行文件如何引用项目模块?(我不认为python语法允许在include语句中使用`../`)
`项目/工程/`?啊,第二个是包名.
如果有人用hello.py和hello-test.py压缩这个布局的样本并使它可用于我们的newbs,那将是很棒的.
@ThorSummoner简单.你安装包!(`pip install -e/path/to/Project`)
@Bloke核心是`-e`标志,它将软件包安装为可编辑的软件包,即将其安装为实际项目文件夹的链接.然后,可执行文件可以只是"导入项目"以访问模块.
@ThorSummoner仅在保留在单个包中时才有效.要在这里工作的相对导入,你需要在`bin`文件夹和`Project`顶部文件夹中都有一个`__init __.py`文件.
在轻率地忽略了这一点之后,我最终不得不将我的东西洗得像这样,以便能够轻松制作出rpms.强烈建议大家默认使用此设置,除非你有充分的理由不这样做.
@ThorSummoner这对我来说实际上是一个非常好的问题,通过调整PYTHON_PATH,我看不出怎么做.在我看来,这种结构使得运行项目启动脚本不必要地复杂化(将'project'文件直接置于项目之下/无需调整PYTHON_PATH).
@Kroltan你能否解释一下`pip install`这个包之后发生了什么,它允许你从`bin`文件夹中很好地运行一个可执行文件,它很好地引用了项目模块?

3> 小智..:

这篇由Jean-Paul Calderone撰写的博客文章通常作为Freenode上#python的回答.

Python项目的文件系统结构

做:

将目录命名为与项目相关的内容.例如,如果您的项目名为"Twisted",请为其源文件命名顶级目录Twisted.执行发布时,应包含版本号后缀:Twisted-2.5.

Twisted/bin如果有的话,创建一个目录并将可执行文件放在那里..py即使它们是Python源文件,也不要给它们扩展.除了导入和调用项目中其他地方定义的main函数之外,不要在其中添加任何代码.(轻微的皱纹:因为在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解释和安装你的软件.

别:

将您的源放在名为src或的目录中lib.这使得在没有安装的情况下很难运行.

把你的测试放在你的Python包之外.这使得难以针对已安装的版本运行测试.

创建一个包含a __init__.py然后将所有代码放入的包__init__.py.只需制作一个模块而不是一个包,它就更简单了.

尝试提出神奇的黑客攻击,使Python能够导入您的模块或包,而无需用户将包含它的目录添加到其导入路径(通过PYTHONPATH或其他一些机制).您将无法正确处理所有情况,当您的软件无法在其环境中工作时,用户会对您生气.


这正是我所需要的."不要尝试提出神奇的黑客攻击,以使Python能够导入您的模块或包,而无需用户将包含它的目录添加到其导入路径中." 很高兴知道!
对于"将您的源代码放在名为src或lib的目录中感到困惑.这使得在没有安装的情况下很难运行." 会安装什么?它是导致问题的目录名称,还是它根本就是一个子目录?
"有些人会声称你应该在你的模块中分发测试 - 我不同意.它通常会增加用户的复杂性;许多测试套件通常需要额外的依赖关系和运行时环境." https://python-guide-pt-br.readthedocs.io/en/latest/writing/structure/#test-suite
“这使得不安装就很难运行。” - 这才是重点*

4> David C. Bis..:

查看正确开源Python项目.

让我摘录一下这篇优秀文章的项目布局部分:

设置项目时,布局(或目录结构)非常重要.合理的布局意味着潜在的贡献者不必花费永远寻找一段代码; 文件位置很直观.由于我们正在处理现有项目,这意味着您可能需要移动一些东西.

让我们从顶部开始吧.大多数项目都有许多顶级文件(如setup.py,README.md,requirements.txt等).每个项目应该有三个目录:

包含项目文档的docs目录

以项目名称命名的目录,用于存储实际的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

如您所见,有一些顶级文件,一个docs目录(生成的是sphinx将生成文档的空目录),一个sandman目录和一个sandman下的测试目录.


我这样做,但更多的是:我有一个顶层Makefile,目标文件是一个使'virtualenv env自动化的'env'目标;./env/bin/pip install -r requirements.txt; ./env/bin/python setup.py开发”,通常也是一个依赖于env的“测试”目标,它还会安装测试依赖项,然后运行py.test。

5> guettli..:

"Python Packaging Authority"有一个示例项目:

https://github.com/pypa/sampleproject

它是一个示例项目,作为Python Packaging用户指南的包装和分发项目教程的辅助手段.



6> KT...:

尝试使用python_boilerplate模板启动项目.它主要遵循最佳实践(例如这里的最佳实践),但如果你发现自己愿意在某个时刻将你的项目分成多个鸡蛋(并且相信我,除了最简单的项目之外的其他任何东西,你都愿意的话).常见的情况是你必须使用其他人的库的本地修​​改版本.

你把源头放在哪里?

对于规模较大的项目,将源分成几个蛋是有意义的.每个鸡蛋都将作为一个单独的setuptools布局PROJECT_ROOT/src/.

你把应用程序启动脚本放在哪里?

理想的选择是将应用程序启动脚本注册为entry_point其中一个鸡蛋.

你把IDE项目放在哪里?

取决于IDE.他们中的许多人将他们的东西保留PROJECT_ROOT/.在项目的根目录中,这很好.

你在哪里进行单位/验收测试?

每个鸡蛋都有一组单独的测试,保存在其PROJECT_ROOT/src//tests目录中.我个人更喜欢py.test用来运行它们.

你在哪里放置非Python数据,如配置文件?

这取决于.可以有不同类型的非Python数据.

"资源",即必须打包在鸡蛋中的数据.这些数据进入相应的egg目录,位于包命名空间内的某个位置.它可以通过pkg_resources包使用.

"配置文件",即非Python文件,它们被视为项目源文件的外部文件,但在应用程序开始运行时必须使用某些值进行初始化.在开发过程中,我更喜欢保留这些文件setuptools.对于部署,可以有各种选项.在Windows importlib.resources上,可以在Linux PROJECT_ROOT/config或Linux上使用%APP_DATA%//config.

生成的文件,即在执行期间可由应用程序创建或修改的文件.我希望/etc/在开发/opt//config期间和Linux部署期间保留它们.

你在哪里为pyd/so二进制扩展模块放置非Python源代码如C++?

PROJECT_ROOT/var

文档通常会进入/varPROJECT_ROOT/src//native(这取决于您是否将某些鸡蛋视为单独的大型项目).一些额外的配置将在PROJECT_ROOT/doc和等文件中PROJECT_ROOT/src//doc.



7> Jason Baker..:

根据我的经验,这只是一个迭代问题.将您的数据和代码放在您认为的任何地方.机会是,你无论如何都会错.但是一旦你更好地了解事情将如何形成,你就可以做出更好的猜测.

至于扩展源,我们在trunk下有一个Code目录,其中包含python的目录和各种其他语言的目录.就个人而言,我更倾向于下次尝试将任何扩展代码放入自己的存储库中.

话虽如此,我回到最初的观点:不要做太大的交易.把它放在似乎适合你的地方.如果你发现一些不起作用的东西,它可以(而且应该)改变.



8> Charles Duff..:

使用setuptools中的package_data支持,非python数据最好捆绑在Python模块中.我强烈建议使用命名空间包创建多个项目可以使用的共享命名空间,这与将包放入(并且能够拥有共享命名空间)的Java约定非常相似.com.yourcompany.yourprojectcom.yourcompany.utils

重新分支和合并,如果你使用一个足够好的源控制系统,它将处理合并,即使通过重命名; Bazaar特别擅长这一点.

相反,这里的一些其他的答案,我+1上有一个src目录的顶层(与doctest目录旁边).文档目录树的具体约定将根据您使用的内容而有所不同; 例如,Sphinx有自己的快速启动工具支持的约定.

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

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有