在工程化上,Python相比于Java,C#这类语言还是差了不少,不过整个生态还是不错的.
项目结构
一般有两种,一种称为flat另一种为src.
├── sample
│ ├── AUTHORS.rst
│ ├── docs
| | ├── conf.py
│ │ └── index.rst
│ ├── HISTORY.rst
│ ├── LICENSE
│ ├── makefile
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── requirements.txt
│ ├── sample
| | ├── app.py
│ │ └── helper.py
| ├── setup.cfg
| ├── setup.py
│ └── tests
主要是使用poetry等工具打包的时候需要注意一下,因为pyproject.toml
字段不完全相同.
FAQ
- ImportError: attempted relative import with no known parent package
包中的模块使用相对导入时不能直接运行该模块,一般是其他包或顶级模块进行调用
工具链
版本管理工具
Anaconda可以同时解决Python版本和包管理的问题,但如果只是想开发个包,没有必要使用conda,在linux上可以考虑pyenv+poetry,windows上有对应的pyenv-windows+poetry.
pyenv允许您轻松地在多个版本的Python之间切换。它简单、不引人注目,并且遵循了UNIX传统的单用途工具,可以很好地完成一件事。
pyenv/pyenv: Simple Python version management (github.com)
包管理工具
目前开发Python包我推荐Poetry或者PDM,如果是搞数据计算直接Anaconda.
Poetry
某种程度上告别setup.py
,除了一般的虚拟环境和包管理之外,打包和发布到PYPI等都支持,也是现在比较火的工具.
虚拟环境管理类似conda,会在某个目录下放所有的虚拟环境
1
2
3poetry init
poetry install
poetry shell
通过初始化一个新的Poetry项目,这将以交互方式生成一个文件pyproject.toml。该文件将具有所有包依赖项。这与requirements.txt文件类似。
当参数 virtualenvs.create
为 true
时,执行 poetry install
或 poetry add
时会检测当前项目是否有虚拟环境,没有就自动创建,默认为 true
。
当参数 virtualenvs.in-project
为 true
时,虚拟环境的依赖将会放置于项目的文件夹内,而不是 poetry 默认的 {cache-dir}/virtualenvs
,默认为 false
。
我的配置如下:
当Poetry完成安装后,它会将所有包及其下载的确切版本写入Poetry.lock文件,从而将项目锁定到这些特定版本。该锁定文件也应包含在您的项目repo中,以便在项目中工作的每个人都被锁定到相同版本的依赖项。
PDM
支持最新PEP标准的现代Python包和依赖项管理器. Poetry的pyproject.toml
与PEP标准不完全符合.
PDM可以管理项目和集中位置的虚拟环境(venv),类似于Pipenv。它从标准化的pyproject.toml文件中读取项目元数据,并支持锁定文件。用户可以通过插件添加额外的功能,这些功能可以通过将其作为分发版上传来共享。与Poetry和Hatch不同,PDM不局限于特定的构建后端;用户可以自由选择他们喜欢的任何构建后端。
Formatter
代码格式化工具,一般用black就够了.
Black
Black是不折不扣的Python代码格式化程序。通过使用它,您同意放弃对手工格式化细节的控制。作为回报,Black为您提供了速度、决定论和自由,使您免受pycode风格对格式的唠叨。你会为更重要的事情节省时间和精力。无论您正在阅读的项目是什么,变黑的代码看起来都是一样的。一段时间后,格式将变得透明,您可以转而关注内容。Black通过产生尽可能小的差异来加快代码审查。1
2pip install black
black {source_file_or_directory}
yapf
YAPF是一个基于clang格式的Python格式化程序(由Daniel Jasper开发)。本质上,该算法采用代码并计算符合配置样式的最佳格式。它省去了维护代码的许多繁琐工作。最终目标是YAPF生成的代码与程序员在遵循样式指南的情况下编写的代码一样好。1
pip install yapf
autopep8
autoep8自动格式化Python代码,以符合PEP8样式指南。它使用pycodestyle实用程序来确定需要格式化代码的哪些部分。autoep8能够修复pycodestyle可能报告的大多数格式问题。1
2pip install --upgrade autopep8
autopep8 --in-place --aggressive --aggressive <filename>
Linter
一般用pylint足矣,喜欢尝鲜的可以用用Ruff.
PyLint
Pylint是Python 2或3的静态代码分析器。最新版本支持Python 3.8.0及以上版本。Pylint在不实际运行代码的情况下分析代码。它检查错误,强制执行编码标准,寻找代码气味,并可以就如何重构代码提出建议。1
pip install pylint
flake8
Flake8是这些工具的包装:PyFlakespycode样式Ned Batchelder的McCabe脚本Flake8通过启动单个Flake8命令来运行所有工具。它在每个文件的合并输出中显示警告。PyCQA/flake8: flake8 is a python tool that glues together pycodestyle, pyflakes, mccabe, and third-party plugins to check the style and quality of some python code. (github.com)
Ruff
比较新的工具astral-sh/ruff: An extremely fast Python linter and code formatter, written in Rust. (github.com),不只是语法提示器,也可以用于格式化.1
2
3
4
5pip install ruff
ruff path/to/code/to/check.py
ruff path/to/code/
ruff path/to/code/*.py
类型检查工具
在Python中使用typing的检查工具,此外与PydanticWelcome to Pydantic - Pydantic搭配使用效果更佳
Pydantic是Python中使用最广泛的数据验证库。Pydantic快速且可扩展,可以很好地处理您的linters/IDE/brain。
定义数据应该如何使用纯规范的Python 3.7+;用Pydantic验证它。
1 | from datetime import datetime |
Mypy
python/mypy: Optional static typing for Python (github.com)
Mypy是Python的静态类型检查器。类型检查器有助于确保您在代码中正确使用变量和函数。
使用mypy,将类型提示(PEP484)添加到Python程序中,当您错误地使用这些类型时,mypy会发出警告。Python是一种动态语言,所以通常只有当你试图运行它时,你才会在代码中看到错误。Mypy是一个静态检查器,所以它甚至不用运行就可以发现程序中的错误!1
2python3 -m pip install -U mypy
mypy PROGRAM
Pyright
microsoft/pyright: Static Type Checker for Python (github.com)
Pyright是一个功能齐全、基于标准的Python静态类型检查器。它是为高性能而设计的,可以与大型Python源代码库一起使用。
Git pre-commit hook
在git commit
之前设置hook进行代码检查
Test
测试工具
Pytest
pytest框架使编写小型可读测试变得容易,并且可以扩展以支持应用程序和库的复杂功能测试。1
pip install -U pytest
参考资料
- python项目结构示例(python代码结构、python目录结构)与python部署结构、python部署目录、flask项目结构、flask目录_python项目结构目录结构-CSDN博客
- 各类Python项目的项目结构及代码组织最佳实践python项目结构__弯弓__的博客-CSDN博客
- Python最佳工程实践,建立一个完美的工程项目 - cuiyubo - 博客园 (cnblogs.com)
- 8 Pre-commit Git Hooks You Must Know for Improved Productivity - Hatica
- 结构化您的工程 — The Hitchhiker’s Guide to Python (pythonguidecn.readthedocs.io)