> Что такое линтеры и форматтеры и как с ними работать (Python)

Уровень: junior · Роль: backend · Язык: Python · Категория: Технические вопросы

Компании: TrueEngineering

Стек: Python

> Пример ответа

Короткий ответ

Линтеры - это инструменты статического анализа, которые проверяют код на соответствие правилам стиля, потенциальные ошибки и "запахи" кода. Форматтеры автоматически приводят код к единому стилю оформления. В Python чаще всего используют Ruff, Flake8, pylint для линтинга и Black, autopep8 для форматирования. Работа с ними строится через конфигурационные файлы (pyproject.toml, .flake8), интеграцию в CI/CD и pre-commit хуки.

Подробное объяснение

Линтеры и форматтеры решают разные, но дополняющие друг друга задачи. Линтер анализирует код без его выполнения: проверяет неиспользуемые переменные, необработанные исключения, нарушение PEP 8, сложность функций, наличие TODO и другие проблемы. Форматтер же переписывает код механически: расставляет отступы, переносы строк, кавычки, пробелы вокруг операторов.

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

В Python экосистема инструментов эволюционировала: раньше использовали связку flake8 + black + isort, сейчас популярен Ruff - он объединяет линтер, форматтер и сортировщик импортов в одном быстром инструменте. Конфигурация обычно хранится в pyproject.toml в секции [tool.ruff] или [tool.black].

Работа с инструментами включает:

  • установку через pip или poetry
  • настройку правил под проект (например, отключить проверку длины строки)
  • запуск локально перед коммитом
  • добавление в pre-commit (через pre-commit framework)
  • запуск в CI на каждый pull request

На практике

Для junior-позиции важно показать понимание workflow, а не только названия инструментов. Типичный сценарий: вы написали код, запустили ruff check . и ruff format ., увидели ошибки, исправили их вручную или автоматически через ruff check --fix. Затем настроили pre-commit, чтобы эти проверки срабатывали автоматически.

В реальном проекте конфигурация может выглядеть так: в pyproject.toml указаны target-version (Python 3.11), выбранные правила (E, F, W из pycodestyle и pyflakes), исключения для тестов, настройка line-length = 100 вместо стандартных 88.

Важно уметь читать вывод линтера: формат ошибки - filename:line:col: code message. Например, app.py:15:5: F401 'os' imported but unused - это ошибка неиспользуемого импорта.

Также стоит знать, что форматтер не всегда "правильный": Black навязывает свой стиль, и команда должна договориться о едином подходе. Иногда форматтер конфликтует с линтером (например, Black переносит строки, а flake8 ругается на сложность), поэтому конфигурации нужно согласовывать.

Пример кода

PYTHON
# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "W", "I"]
ignore = ["E501"] # длина строки уже контролируется форматтером
[tool.ruff.format]
quote-style = "double"
BASH
# установка и запуск
pip install ruff
ruff check . # проверить все файлы
ruff check --fix . # автоматически исправить
ruff format . # отформатировать код
YAML
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format

Как отвечать на собеседовании

Начните с чёткого определения: линтер - статический анализатор, форматтер - автоматический стилизатор. Приведите примеры для Python: Ruff, Flake8, Black. Объясните, зачем это нужно: единый стиль кода, раннее обнаружение ошибок, экономия времени на code review.

Расскажите про workflow: установка, настройка через pyproject.toml, запуск локально, pre-commit, CI. Упомяните, что линтер может находить реальные баги, а не только стилевые проблемы - это сильный аргумент.

Если спросят про конфликты, скажите: Black и flake8 могут спорить о длине строк, поэтому в конфиге отключают E501, а line-length задают одинаково. Это покажет практический опыт.

Завершите примером: "Я бы настроил Ruff, потому что он быстрее и заменяет три инструмента, а в CI добавил бы проверку, чтобы код без линтера не попадал в main".

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание разницы между линтером и форматтером
  • знание конкретных инструментов в Python-экосистеме
  • умение настроить инструменты под проект
  • понимание места линтеров в процессе разработки (pre-commit, CI)
  • способность объяснить, зачем это нужно команде

Для junior достаточно уверенно назвать инструменты и описать базовый сценарий. Хороший сигнал - упоминание Ruff как современного решения и понимание, что линтер ловит не только стиль, но и ошибки.

Типичные ошибки

  • Путать линтер и форматтер, говорить, что "линтер форматирует код"
  • Называть только Black, забывая про линтеры
  • Не знать, где хранится конфигурация (pyproject.toml, setup.cfg, .flake8)
  • Говорить, что линтер "замедляет разработку" - на самом деле он ускоряет ревью
  • Не упоминать pre-commit и CI - это ключевая часть практики
  • Утверждать, что форматтер исправляет ошибки - он меняет только оформление
  • Игнорировать вопрос про конфликты между инструментами - лучше признать, что они бывают, и объяснить решение

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью