Home>Article>Backend Development> Build a perfect Python project

Build a perfect Python project

coldplay.xixi
coldplay.xixi forward
2020-09-29 16:39:11 2540browse

python video tutorialcolumn introduces how to build a perfect Python project.

Build a perfect Python project

#When starting a new Python project, it’s easy to jump in and start coding. In fact, taking a little time to choose excellent libraries will save a lot of time in future development and bring a happier coding experience.

In an ideal world, the relationship between all developers is interdependent and related (collaborative development), the code must be perfectly formatted, there are no low-level errors, and the tests cover all code. Plus, all of this will be guaranteed on every commit. (Uniform code style, type detection, high test coverage, automatic detection)

In this article, I will introduce how to build a project that can achieve these points. You can follow the steps, or you can jump directly to theBuild a project using cookiecuttersection (for experienced users). First, let’s create a new project directory:

mkdir best_practices cd best_practices复制代码

pipx Command-line tool to install Python third-party libraries

Pipx is a command-line tool that can be used to quickly install Python third-party libraries. We will use this to install pipenv and cookiecutter. Install pipx through the following command:

python3 -m pip install --user pipx python3 -m pipx ensurepath复制代码

Use pipenv for dependency management

Pipenv automatically creates and manages virtualenv (virtual environment) for your project, and installs/uninstalls packages. When adding/removing packages from Pipfile. It will also generate the very important Pipfile.lock to ensure the reliability of dependencies.

It will greatly increase the confidence and fun of programming when you know that you and your teammates are using the same library version. Pipenv well solves the problem of using the same library with different versions. Pipenv has gained widespread attention and recognition in the past period, and you can use it with confidence. The installation command is as follows:

pipx install pipenv复制代码

Use black and isort for code formatting

black can format our code:

Black is uncompromising Python code Formatting library. By using it, you'll forego the details of manually adjusting code formatting. In return, Black brings speed, certainty, and the avoidance of the hassle of adjusting Python coding style, leaving more energy and time to focus on more important things.

No matter what kind of project you are reading, code formatted with black will look the same. After a while formatting becomes less of an issue and you can focus more on the content.

black makes code inspection faster by reducing code variability.

And isor sorts our imports part:

isor sorts the Python package parts (imports) you import, so you don’t have to do the imports anymore Manual sorting. It can sort imports alphabetically and automatically split them into parts.

Use pipenv to install it so they don't clutter the deployment (you can specify to install only in development environments):

pipenv install black isort --dev复制代码

Black and isort are not compatible with the default options, so we Will make isort follow the principle of black. Create asetup.cfgfile and add the following configuration:

[isort] multi_line_output=3 include_trailing_comma=True force_grid_wrap=0 use_parentheses=True line_length=88复制代码

We can run these tools using the following command:

pipenv run black pipenv run isort复制代码

Use flake8 to ensure code style

Flake8 ensures that code follows standard Python coding conventions defined in PEP8. Install using pipenv:

pipenv install flake8 --dev复制代码

Just like isort, it requires some configuration to work well with black. Add these configurations tosetup.cfg:

[flake8] ignore = E203, E266, E501, W503 max-line-length = 88 max-complexity = 18 select = B,C,E,F,W,T4复制代码

Now we can run flake8 with the command:pipenv run flake8.

Static type checking using mypy

Mypy is a non-enforced static type checker for Python, designed to combine the advantages of dynamic (or "duck") typing and static typing. Mypy combines the expressive power and convenience of Python with the compile-time type checking of a powerful type system, running them using any Python VM with essentially no runtime overhead.

Using types in Python takes a little getting used to, but the benefits are huge. As follows:

  • Static typing can make the program easier to understand and maintain
  • Static typing can help you find errors earlier and reduce testing and debugging time
  • Static typing can help you catch hard-to-find errors before your code goes into production
pipenv install mypy --dev复制代码

By default, Mypy will recursively check the type annotations of all imported packages, and when the library does not contain these annotations, it will An error will be reported. We need to configure mypy to only run on our code and ignore import errors without type annotations. We assume our code is in thebest_practicespackage configured below. Add this tosetup.cfg:

[mypy]files=best_practices,testignore_missing_imports=true复制代码

Now we can run mypy:

pipenv run mypy复制代码

Here is a useful cheat sheet.

用 pytest 和 pytest-cov 进行测试

使用 pytest 编写测试非常容易,消除编写测试的阻力意味着可以快速的编写更多的测试!

pipenv install pytest pytest-cov --dev复制代码

这是 pytest 网站上的一个简单示例:

# content of test_sample.pydef inc(x): return x + 1def test_answer(): assert inc(3) == 5复制代码

要执行它:

$ pipenv run pytest=========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y cachedir: $PYTHON_PREFIX/.pytest_cache rootdir: $REGENDOC_TMPDIR collected 1 item test_sample.py F [100%] ================================= FAILURES ================================= _______________________________ test_answer ________________________________ def test_answer():> assert inc(3) == 5E assert 4 == 5 E + where 4 = inc(3) test_sample.py:6: AssertionError ========================= 1 failed in 0.12 seconds =========================复制代码

我们所有的测试代码都放在test目录中,因此请将此目录添加到setup.cfg

[tool:pytest] testpaths=test复制代码

如果还想查看测试覆盖率。创建一个新文件.coveragerc,指定只返回我们的项目代码的覆盖率统计信息。比如示例的best_practices项目,设置如下:

[run] source = best_practices [report] exclude_lines = # Have to re-enable the standard pragma pragma: no cover # Don't complain about missing debug-only code: def __repr__ if self\.debug # Don't complain if tests don't hit defensive assertion code: raise AssertionError raise NotImplementedError # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.:复制代码

现在,我们就可以运行测试并查看覆盖率了。

pipenv run pytest --cov --cov-fail-under=100复制代码

--cov-fail-under=100是设定项目的测试覆盖率如果小于 100% 那将认定为失败。

pre-commit 的 Git hooks

Git hooks 可让您在想要提交或推送时随时运行脚本。这使我们能够在每次提交/推送时,自动运行所有检测和测试。pre-commit 可轻松配置这些 hooks。

Git hook 脚本对于在提交代码审查之前,识别简单问题很有用。我们在每次提交时都将运行 hooks,以自动指出代码中的问题,例如缺少分号、尾随空白和调试语句。通过在 code review 之前指出这些问题,代码审查者可以专注于变更的代码内容,而不会浪费时间处理这些琐碎的样式问题。

在这里,我们将上述所有工具配置为在提交 Python 代码改动时执行(git commit),然后仅在推送时运行 pytest coverage(因为测试要在最后一步)。创建一个新文件.pre-commit-config.yaml,配置如下:

repos: - repo: local hooks: - id: isort name: isort stages: [commit] language: system entry: pipenv run isort types: [python] - id: black name: black stages: [commit] language: system entry: pipenv run black types: [python] - id: flake8 name: flake8 stages: [commit] language: system entry: pipenv run flake8 types: [python] exclude: setup.py - id: mypy name: mypy stages: [commit] language: system entry: pipenv run mypy types: [python] pass_filenames: false - id: pytest name: pytest stages: [commit] language: system entry: pipenv run pytest types: [python] - id: pytest-cov name: pytest stages: [push] language: system entry: pipenv run pytest --cov --cov-fail-under=100 types: [python] pass_filenames: false复制代码

如果需要跳过这些 hooks,可以运行git commit --no-verifygit push --no-verify

使用 cookiecutter 生成项目

现在,我们已经知道了理想项目中包含了什么,我们可以将其转换为 模板 从而可以使用单个命令生成一个包含这些库和配置的新项目:

pipx run cookiecutter gh:sourcery-ai/python-best-practices-cookiecutter复制代码

填写项目名称和仓库名称,将为您生成新的项目。

要完成设置,请执行下列步骤:

# Enter project directorycd # Initialise git repogit init# Install dependenciespipenv install --dev# Setup pre-commit and pre-push hookspipenv run pre-commit install -t pre-commit pipenv run pre-commit install -t pre-push复制代码

模板项目包含一个非常简单的 Python 文件和测试,可以试用上面这些工具。在编写完代码觉得没问题后,就可以执行第一次git commit,所有的 hooks 都将运行。

集成到编辑器

虽然在提交时知道项目的代码始终保持最高水准是件令人兴奋的事情。但如果在代码已全部修改完成之后(提交时),再发现有问题还是会让人很不爽。所以,实时暴露出问题要好得多。

在保存文件时,花一些时间确保代码编辑器运行这些命令。有及时的反馈,这意味着你可以在代码还有印象的时候能迅速解决引入的任何小问题。

我个人使用一些出色的 Vim 插件来完成此任务:

  • ale 实时运行 flake8 并在保存文件时运行 black、isort 和 mypy
  • 与 projectionist 集成的 vim-test 在文件保存上运行 pytest

欢迎热爱技术和开源的小伙伴加入 HG 推出的译文亦舞系列的翻译中来,可以留言告诉我们。

更多相关免费学习推荐:python视频教程

The above is the detailed content of Build a perfect Python project. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete