Python项目代码结构与编码规范

Quarterback 2022年07月20日 1,969次浏览

1、The Zen of Python(Python之禅)
2、convention over configuration(约定优于配置)
3、Python项目代码结构及项目构建工具:推荐、CookieCutter、PyScaffold、PyBuilder、Poetry
4、Python编码规范:PEP 8、Google Python编码规范

1、The Zen of Python(Python之禅)

在正式进入学习Python开发之前,找寻了下Python是否包含关于项目代码结构约定,是否有推荐的编码规范,于是发现了这个:Python解释器中关于Python编程思想的彩蛋——《The Zen of Python》。
能把编码上升到哲学,一般都不是一般人,作者Tim Peters,人称Timbot、无情的代码写作机、归并排序算法TimSort的作者。TimSort在Java和Python数组排序中都有被采用。

>>> import this

《The Zen of Python》, by Tim Peters
Python之禅语——作者Tim Peters

Beautiful is better than ugly.
# 优雅胜于丑陋.
Explicit is better than implicit.
# 明确胜于晦暗.
Simple is better than complex.
# 简洁胜于繁复.
Complex is better than complicated.
# 繁复胜于艰深.
Flat is better than nested.
# 扁平胜于嵌套.
Sparse is better than dense.
# 松散胜于聚集.
Readability counts.
# 代码确保易读.
Special cases aren't special enough to break the rules.
# 规则拒绝特例.
Although practicality beats purity.
# 实用不求纯净.
Errors should never pass silently.
# 错误不可放过.
Unless explicitly silenced.
# 除非明确理由.
In the face of ambiguity, refuse the temptation to guess.
# 模棱两可之间,不要随意猜测.
There should be one-- and preferably only one --obvious way to do it.
# 必有唯一选择,明显胜过其余.
Although that way may not be obvious at first unless you're Dutch.
# 起初无法分辨,只因你非大神.
Now is better than never.
# 尝试好过放弃.
Although never is often better than *right* now.
# 但须谋定而动.
If the implementation is hard to explain, it's a bad idea.
# 实现难以解释,定是糟糕方案.
If the implementation is easy to explain, it may be a good idea.
# 实现易于解释,或为良好方案.
Namespaces are one honking great idea -- let's do more of those!
# 命名空间极好,诸君多加使用!
可恶 被他装到了
可恶 被他装到了

哲学就是这样,感觉说了很多,但感觉好像又等于什么都没说。但是其实这些编码思想,对于不同语言的编程来说都是适用的,并且根据这些思想为指导,可以更好的进行编码和协作。

2、convention over configuration(约定优于配置)

在Java中,如今Maven和Gradle已经成为了Java项目构建和管理的标准工具。
对于Java项目,Maven有一个很好的指导思想来约束Java项目结构:即所谓的约定优于配置。这与Python之禅中的“规则拒绝特例”有异曲同工之处。
一千个观众眼里就有一千个哈姆雷特,但是一千个项目最好都是一样的项目结构。对于这种不需要个性化或创造性的地方,固化的约定通常是最好的方式,因为它不仅让不同的开发协作者或维护者减少了阅读代码的成本,同时对于Maven这样的项目构建工具,也减少了实现难度。

3、Python项目代码结构

但是,在Python中,虽然有自带的包管理或流行的第三方包管理及构建工具,但似乎好像并未形成对Python项目结构普遍共识的约定。或者,我没有找到。
下面是我找到的一些推荐的项目结构,或者一些第三方项目结构(或项目脚手架)生成工具生成的项目结构。不知道Pythoner常用的是哪个?
个人感觉应该1、2(Kenneth推荐目录结构、CookieCutter生成的项目结构)更靠谱些,因为从目录结构上看确实比较科学、全面,并且是围绕官方构建工具组织的结构。

Kenneth推荐目录结构

据说是Python社区大神Kenneth Reitz推荐的Python项目结构:

sample-python-project
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── docs
│   ├── Makefile
│   ├── conf.py
│   ├── index.rst
│   └── make.bat
├── requirements.txt
├── sample
│   ├── __init__.py
│   ├── core.py
│   └── helpers.py
├── setup.py
└── tests
    ├── __init__.py
    ├── context.py
    ├── test_advanced.py
    └── test_basic.py
CookieCutter

cookiecutter 是一个命令行工具,用于根据项目模板创建基础的项目框架。
cookiecutter工具github地址:https://github.com/cookiecutter/cookiecutter
cookiecutter推荐使用的项目模板:https://github.com/audreyfeldroy/cookiecutter-pypackage
可以通过如下命令生成如下项目结构:cookiecutter gh:audreyfeldroy/cookiecutter-pypackage
可以看到该模板生成的结构和上述Kenneth推荐目录结构基本一致。

sample-python-project
├── AUTHORS.rst
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── docs
│   ├── Makefile
│   ├── authors.rst
│   ├── conf.py
│   ├── contributing.rst
│   ├── history.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── make.bat
│   ├── readme.rst
│   └── usage.rst
├── requirements_dev.txt
├── sample
│   ├── __init__.py
│   ├── cli.py
│   └── sample.py
├── setup.cfg
├── setup.py
├── tests
│   ├── __init__.py
│   └── test_sample.py
└── tox.ini

AUTHORS.rst:扩展名为.rst的文件是reStructuredText的纯文本文件,含义为”重新构建的文本“,是python编程语言的Docutils项目的一部分。简单的来说reStructuredText是一种轻量级的文本标记语言,简单易读,所见即所得的文本标记语言。
项目开发人员和贡献人员相关信息。
CONTRIBUTING.rst:关于如何对项目贡献反馈相关说明。
HISTORY.rst:项目版本变更历史记录。
LICENSE:项目使用许可或开源协议声明。
MANIFEST.in:简而言之,MANIFEST.in用于打包除python程序之外的文件。默认情况下,当打包python代码(使用python setup.py sdist)以创建压缩存档以进行分发时,打包程序将仅在软件包存档中包含一组特定文件(python代码)本身)。如果存储库中包含文本文件(例如,模板)或图形(用于文档),该怎么办?默认情况下,打包程序不会在归档文件中包含这些文件,并且它是不完整的。MANIFEST.in允许您覆盖默认值,确切指定需要在zip存档中包含哪些文件才能分发。
Makefile:通过make工具构建、测试、部署项目。可以大大简化你的CI/CD 流程脚本,因为你只需要简单地调用对应的make命令即可。
README.rst:项目概述文档。

docs

  • Makefile:在docs/文件夹中,Makefile由Sphinx自动生成。此Makefile是独立的,并且完全独立于存储库根目录中的Makefile或common.mk文件。我可以发出类似的命令make html,它将使用Sphinx生成HTML格式的文档
  • authors.rst
  • conf.py:sphinx的配置文件。
  • contributing.rst
  • history.rst
  • index.rst:index.rst是Sphinx默认生成的主文档,包括文档的目录索引。
  • installation.rst:项目安装说明文档。
  • make.bat:Sphinx自动生成的bat文件,用于windows下提供命令行工具。
  • readme.rst
  • usage.rst:项目/模块使用说明。

requirements_dev.txt:项目依赖包信息,使用pip install安装项目的时候会根据该文件安装项目依赖包。_dev表示用于开发环境,由于存在多个环境,因此可以使用不同的requirement文件来区分。
sample:sample目录下为项目源码。

  • __init__.py:将文件夹变为一个Python模块,Python 中的每个模块的包中,都有init.py文件
  • cli.py:命令行接口。
  • sample.py:模块代码。

setup.cfg:setuptools推荐从setup.py迁移到setup.cfg。使用setup.cfg而不是setup.py的理由是,前者是声明式的配置文件,后者是实际的python代码,可能不安全。
setup.py:基于setuptools包分发和安装工具,用于模块的分发和安装。 setup.py 文件编写的规则是从setuptools 导入 setup 及其它一些 辅助 模块函数, 并传入各类参数进行调用。
tests:单元测试。

  • __init__.py
  • test_sample.py

tox.ini:python自动化工具tox的配置文件。

PyScaffold

略。详细参考:https://github.com/pyscaffold/pyscaffold

PyBuilder

略。详细参考:https://pybuilder.io/documentation/tutorial

Poetry

略。详细参考:https://github.com/python-poetry/poetry

4、Python编码规范:PEP 8、Google Python编码规范

PEP 8

PEP是Python Enhancement Proposal的缩写,通常翻译为“Python增强提案”。每个PEP都是一份为Python社区提供的指导Python往更好的方向发展的技术文档,其中的第8号增强提案(PEP 8)是针对Python语言编订的代码风格指南。
它包括了对Python编码缩进、行的最大长度、注释、文档字符串、基本原则、命名风格、命名约定等一系列编码风格、规范的指导说明。
详细参考官方文档:
地址:https://www.python.org/dev/peps/pep-0008/
中文翻译:https://python.freelycode.com/contribution/detail/47

另外,在编码IDE中,例如pycharm中,是可以设置PEP 8编码规范提示。类似Java中阿里的P3C插件。

Google Python编码规范

大厂出品,还是有说服力的。类似Java领域,阿里出的Java编程规范一样。
地址:https://google.github.io/styleguide/pyguide.html

--EOF--