Как создать идеальный проект Python

Python
Как создать идеальный проект Python
  • Оригинальный адрес:How to set up a perfect Python project
  • Оригинальный автор: Брендан Магиннис
  • Переводчик: HelloGitHub-Яя
  • Корректор: HelloGitHub — Cut Weihan

Когда вы начинаете новый проект Python, легко сразу же приступить к написанию кода. На самом деле, если вы потратите немного времени на выбор хорошей библиотеки, это сэкономит много времени при разработке в будущем и сделает кодирование более приятным.

В идеальном мире все отношения разработчиков взаимозависимы и взаимосвязаны (совместная разработка), код идеально отформатирован, низкоуровневые ошибки отсутствуют, а тесты охватывают весь код. Кроме того, все это будет гарантировано при каждом коммите. (унифицированный стиль кода, определение типа, высокое тестовое покрытие, автоматическое определение)

В этой статье я опишу, как настроить проект, который может делать эти вещи. Вы можете следовать инструкциям или сразу перейти кСоздайте проект с помощью cookiecutterчасть (ветеранская). Во-первых, давайте создадим новый каталог проекта:

mkdir best_practices
cd best_practices

pipx — это инструмент командной строки для установки сторонних библиотек Python.

Pipx— это инструмент командной строки, который можно использовать для быстрой установки сторонних библиотек Python. Мы будем использовать его для установки pipenv и cookiecutter. Установите Pipx с помощью следующей команды:

python3 -m pip install --user pipx
python3 -m pipx ensurepath

Управление зависимостями с помощью pipenv

PipenvАвтоматически создавайте и управляйте virtualenv (виртуальными средами) для вашего проекта, а также добавляйте/удаляйте пакеты из Pipfile при установке/удалении пакетов. Он также генерирует очень важный Pipfile.lock для обеспечения надежности зависимостей.

Когда вы знаете, что вы и ваши товарищи по команде используете одну и ту же версию библиотеки, это значительно повысит уверенность и удовольствие от программирования. Pipenv решил проблему использования одной и той же библиотеки с разными версиями.Pipenv получил широкое внимание и признание за прошедший период времени, и вы можете использовать его с уверенностью. Команда установки выглядит следующим образом:

pipx install pipenv

Форматирование кода с помощью черного и isort

blackМы можем отформатировать наш код:

Black — это бескомпромиссная библиотека форматирования кода Python. Используя его, вы забудете о деталях ручного форматирования кода. В свою очередь, Black обеспечивает скорость, уверенность и позволяет избежать хлопот по настройке стиля кода Python, позволяя больше энергии и времени сосредоточиться на более важных вещах.

Код, отформатированный черным цветом, выглядит одинаково независимо от того, какой проект вы читаете. Через некоторое время форматирование перестает быть проблемой, поэтому вы можете больше сосредоточиться на содержании.

черный ускоряет проверку кода за счет уменьшения дисперсии кода.

иisortзаключается в сортировке нашего раздела импорта:

isort сортирует ваши импортированные части пакета Python (импорт), поэтому вам больше не нужно вручную сортировать импорт. Он может сортировать импорт в алфавитном порядке и автоматически разбивать его на части.

Установите его с помощью pipenv, чтобы они не загромождали развертывание (можно указать для установки только в процессе разработки):

pipenv install black isort --dev

Черный и isort не являются совместимыми вариантами по умолчанию, поэтому мы заставим isort следовать принципу черного. Создаватьsetup.cfgДокумент и добавьте следующую конфигурацию:

[isort]
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88

Мы можем запустить эти инструменты со следующими командами:

pipenv run black
pipenv run isort

Гарантированный стиль кода с Flake8

Flake8 гарантирует, что код соответствует стандартным соглашениям о коде Python, определенным в PEP8. Установить с помощью pipenv:

pipenv install flake8 --dev

Как и isort, он требует некоторой настройки, чтобы хорошо играть черным цветом. добавьте эти конфиги вsetup.cfg:

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

Теперь мы можем запустить flake8 командой:pipenv run flake8.

Статическая проверка типов с помощью mypy

Mypyэто не принудительная статическая проверка типов для Python, разработанная для объединения преимуществ динамической (или «утиной») типизации и статической типизации. Mypy сочетает в себе выразительность и удобство Python с проверкой типов во время компиляции мощной системы типов, запуская их с использованием любой виртуальной машины Python практически без накладных расходов во время выполнения.

К использованию типов в Python нужно немного привыкнуть, но преимущества огромны. следующее:

  • Статическая типизация может упростить понимание и обслуживание программ.
  • Статическая типизация может помочь вам обнаружить ошибки раньше и сократить время тестирования и отладки.
  • Статическая типизация может помочь вам обнаружить трудно обнаруживаемые ошибки до того, как ваш код будет запущен в производство.
pipenv install mypy --dev

По умолчанию Mypy проверит аннотацию типа всех пакетов импорта. Когда библиотека не содержит этих комментариев, она сообщит об ошибке. Нам нужно настроить mypy для запуска на нашем коде и игнорировать ошибки импорта без аннотаций типа. Мы предполагаем, что наш код расположен нижеbest_practicesв сумке. добавить это кsetup.cfg:

[mypy]
files=best_practices,test
ignore_missing_imports=true

Теперь мы можем запустить mypy:

pipenv run mypy

это полезношпаргалка.

Тестирование с помощью pytest и pytest-cov

использоватьpytestПисать тесты очень легко, а устранение трений при написании тестов означает, что можно быстро написать больше тестов!

pipenv install pytest pytest-cov --dev

Вот простой пример с сайта pytest:

# content of test_sample.py
def inc(x):
    return x + 1

def 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) == 5
E       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%, то это будет считаться провалом.

Git-хуки для предварительной фиксации

Git-хуки позволяют вам запускать скрипты в любое время, когда вы хотите зафиксировать или отправить. Это позволяет нам автоматически запускать все инструменты и тесты при каждой фиксации/нажатии.pre-commitЭти хуки можно легко настроить.

Сценарии Git hook полезны для выявления простых проблем перед отправкой на проверку кода. Мы будем запускать хуки при каждом коммите, чтобы автоматически указывать на проблемы в коде, такие как отсутствие точек с запятой, пробелы в конце и операторы отладки. Указав на эти проблемы до проверки кода, рецензент кода может сосредоточиться на измененном содержании кода, не тратя время на решение этих тривиальных проблем со стилем.

Здесь мы настраиваем все вышеперечисленные инструменты для выполнения при фиксации изменений в коде Python (git commit), а затем запускаем покрытие pytest только при отправке (поскольку тестирование — последний шаг). Создать новый файл.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

Если вам нужно пропустить эти хуки, вы можете запуститьgit commit --no-verifyилиgit push --no-verify

Создайте проект с помощью cookiecutter

Теперь, когда мы знаем, что входит в идеальный проект, мы можем преобразовать его вшаблонЭто позволяет сгенерировать новый проект, содержащий эти библиотеки и конфигурации, с помощью одной команды:

pipx run cookiecutter gh:sourcery-ai/python-best-practices-cookiecutter

Заполните имя проекта и имя репозитория, и для вас будет создан новый проект.

Чтобы завершить настройку, выполните следующие действия:

# Enter project directory
cd <repo_name>

# Initialise git repo
git init

# Install dependencies
pipenv install --dev

# Setup pre-commit and pre-push hooks
pipenv run pre-commit install -t pre-commit
pipenv run pre-commit install -t pre-push

Проект шаблона содержит очень простой файл Python и тесты для опробования этих инструментов. Написав код и почувствовав, что проблем нет, можно выполнять с первого разаgit commit, все хуки будут запущены.

интегрирован в редактор

Хотя во время коммита приятно знать, что код вашего проекта всегда находится на самом высоком уровне. Но если код весь был изменен (на момент отправки), все равно очень неудобно обнаружить, что есть проблема. Таким образом, гораздо лучше выявлять проблемы в режиме реального времени.

Потратьте некоторое время, чтобы убедиться, что редактор кода выполняет эти команды при сохранении файла. Существует немедленная обратная связь, что означает, что вы можете быстро решить любые незначительные проблемы, возникшие, пока код все еще впечатывается.

Я лично использую для этой задачи несколько замечательных плагинов Vim:

Друзья, которые любят технологии и открытый исходный код, могут присоединиться к переводу серии переводов и танцев, запущенной HG, и вы можете оставить сообщение, чтобы рассказать нам.