- Оригинальный адрес: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:
- aleЗапускаем flake8 live и запускаем black, isort и mypy при сохранении файлов
- иинтегрированный киномеханик vim-testзапустить pytest при сохранении файла
Друзья, которые любят технологии и открытый исходный код, могут присоединиться к переводу серии переводов и танцев, запущенной HG, и вы можете оставить сообщение, чтобы рассказать нам.