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

Build a perfect Python project

coldplay.xixi
Release: 2020-09-29 16:39:11
forward
2642 people have browsed it

python video tutorial column 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 the Build a project using cookiecutter section (for experienced users). First, let’s create a new project directory:

mkdir best_practices
cd best_practices复制代码
Copy after login

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复制代码
Copy after login

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复制代码
Copy after login

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复制代码
Copy after login

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

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

We can run these tools using the following command:

pipenv run black
pipenv run isort复制代码
Copy after login

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复制代码
Copy after login

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

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

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复制代码
Copy after login

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 the best_practices package configured below. Add this to setup.cfg:

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

Now we can run mypy:

pipenv run mypy复制代码
Copy after login

Here is a useful cheat sheet.

用 pytest 和 pytest-cov 进行测试

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

pipenv install pytest pytest-cov --dev复制代码
Copy after login

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

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

要执行它:

$ 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 =========================复制代码
Copy after login

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

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

如果还想查看测试覆盖率。创建一个新文件 .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__.:复制代码
Copy after login

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

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

--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复制代码
Copy after login

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

使用 cookiecutter 生成项目

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

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

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

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

# Enter project directorycd <repo_name># 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复制代码
Copy after login

模板项目包含一个非常简单的 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!

Related labels:
source:juejin.im
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template