Стандарты оформления docstring в Python: пишем понятную документацию

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Python-разработчики, желающие улучшить качество своего кода
  • Студенты и новички в программировании, изучающие стандарты написания кода
  • Руководители команд разработки, заинтересованные в повышении эффективности работы группы

    Код на Python как открытая книга — прочитать может каждый, но извлечь из неё пользу могут лишь те, кто разбирается в авторском стиле. Подобно тому, как литературные произведения имеют предсказуемую структуру, Python-код также должен следовать определенным конвенциям, особенно когда речь идет о документировании кода. Именно docstring и стандарты PEP превращают бессистемный набор функций в удобочитаемый, профессиональный код, который становится понятным с первого взгляда и не требует дополнительных усилий для расшифровки. 📚

Если вы хотите писать код, который не вызовет рвотного рефлекса у коллег на код-ревью, стоит освоить стандарты документирования в Python. На курсе Обучение Python-разработке от Skypro вы не только научитесь писать чистый код, но и поймете, как правильно его документировать согласно стандартам PEP 8 и PEP 257. Именно этот навык отличает профессионала от новичка и повышает вашу ценность как специалиста.

Что такое docstring и зачем нужны стандарты в Python

Docstring (сокращение от "documentation string") — это строка документации, которая служит для описания модулей, классов, функций и методов в Python. Она размещается сразу после объявления и перед телом кода, заключённая в тройные кавычки, что делает её многострочной по умолчанию.

Но зачем тратить время на написание документации, когда можно просто писать код? 🤔 Причина проста: код пишется один раз, а читается многократно — как вами, так и другими разработчиками.

Алексей Смирнов, технический лид в команде разработки

Как-то раз мы унаследовали проект от команды, которая полностью игнорировала docstrings. Я потратил почти две недели, разбираясь в кодовой базе размером примерно в 30 000 строк. Функции с неочевидными названиями вроде process_data или handle_exception без документации превращались в настоящие головоломки. После этого кейса я ввёл в команде правило: код без docstring не проходит ревью. За три месяца производительность выросла на 30%, а количество багов снизилось вдвое — просто потому, что все стали лучше понимать, что и как работает.

Стандарты документирования в Python решают несколько ключевых проблем:

  • Снижение когнитивной нагрузки — не нужно "держать в голове" всю логику кода
  • Единообразие — одинаковый формат документации делает работу предсказуемой
  • Автоматизация — docstrings используются для генерации документации инструментами вроде Sphinx
  • Интеграция в IDE — современные редакторы показывают docstring при наведении на функцию

Согласно исследованию Stack Overflow, более 70% разработчиков тратят больше времени на чтение существующего кода, чем на написание нового. Именно поэтому стандарты документации — это не прихоть, а необходимость в профессиональной разработке.

Характеристика Код без docstring Код с docstring
Время на понимание нового кода В среднем 2-3 часа 30-60 минут
Скорость онбординга новых сотрудников 2-3 недели 1-1.5 недели
Количество уточняющих вопросов Высокое Низкое
Возможность автоматической генерации документации Отсутствует Есть
Пошаговый план для смены профессии

Основные требования PEP 257 для оформления документации

PEP 257 — это документ, который определяет стандарты для написания docstring в Python. Разработанный Гвидо ван Россумом, Барри Варшавом и Дэвидом Гудгером, этот стандарт устанавливает базовые правила, которые должен соблюдать каждый Python-разработчик.

Основные требования PEP 257:

  • Все публичные модули, функции, классы и методы должны иметь docstrings. Не-публичные методы могут обойтись и без них, но все равно должны иметь комментарии, описывающие их функциональность.
  • Docstring должен быть понятным в качестве текстового сообщения. Пишите его так, будто объясняете функциональность коллеге за обедом.
  • Однострочные docstrings должны быть действительно однострочными. Тройные кавычки открываются и закрываются на той же строке.
  • Многострочные docstrings должны иметь резюме в первой строке, за которым следует пустая строка, а затем более подробное описание.
  • Избегайте повторения имени функции/метода в docstring — это избыточно и усложняет чтение.

Вот пример правильного однострочного docstring:

Python
Скопировать код
def get_user_by_id(user_id):
"""Return user object for the given user ID."""
return db.query(User).filter(User.id == user_id).first()

И пример правильного многострочного docstring:

Python
Скопировать код
def calculate_tax(income, tax_rate=0.2):
"""Calculate tax amount based on income and tax rate.

Args:
income (float): Gross income amount.
tax_rate (float, optional): Tax rate as a decimal. Defaults to 0.2.

Returns:
float: Calculated tax amount.

Raises:
ValueError: If income is negative.
"""
if income < 0:
raise ValueError("Income cannot be negative")
return income * tax_rate

Важно помнить, что docstring должен обеспечивать достаточную информацию для использования функции или класса без необходимости заглядывать в исходный код. Это особенно важно для библиотек и API, где пользователи могут не иметь доступа к исходникам.

Популярные стили форматирования docstring: сравнение подходов

PEP 257 устанавливает лишь базовые правила для docstring, но не определяет конкретный формат структурирования информации внутри документации. Именно поэтому в сообществе Python сформировались несколько популярных стилей, каждый со своими особенностями. 🔍

Стиль Особенности Популярность Подходит для
Google style Секции выделяются заголовками, аргументы описываются в формате "name (type): description" Очень высокая Большинство проектов, особенно с TensorFlow и другими Google-технологиями
NumPy style Расширение Google style с более подробным форматированием для научных проектов Высокая в научной среде Научные вычисления, анализ данных, проекты с NumPy/SciPy/Pandas
reStructuredText (reST) Использует специальные директивы Sphinx, более формальный синтаксис Средняя Проекты с генерацией документации Sphinx, многие стандартные библиотеки Python
Epytext Формат, подобный JavaDoc Низкая Устаревшие проекты

Рассмотрим примеры трёх наиболее распространённых стилей для одной и той же функции:

1. Google style:

Python
Скопировать код
def connect_to_database(host, port=5432, user=None, password=None):
"""Establishes connection to PostgreSQL database.

Args:
host (str): Database server hostname or IP address.
port (int, optional): Port number. Defaults to 5432.
user (str, optional): Username for authentication. If None, uses system user.
password (str, optional): Password for authentication.

Returns:
Connection: Database connection object.

Raises:
ConnectionError: If connection cannot be established.
"""

2. NumPy style:

Python
Скопировать код
def connect_to_database(host, port=5432, user=None, password=None):
"""Establishes connection to PostgreSQL database.

Parameters
----------
host : str
Database server hostname or IP address.
port : int, optional
Port number. Default is 5432.
user : str, optional
Username for authentication. If None, uses system user.
password : str, optional
Password for authentication.

Returns
-------
Connection
Database connection object.

Raises
------
ConnectionError
If connection cannot be established.
"""

3. reStructuredText (reST):

Python
Скопировать код
def connect_to_database(host, port=5432, user=None, password=None):
"""Establishes connection to PostgreSQL database.

:param host: Database server hostname or IP address.
:type host: str
:param port: Port number, defaults to 5432
:type port: int, optional
:param user: Username for authentication, if None uses system user
:type user: str, optional
:param password: Password for authentication
:type password: str, optional

:returns: Database connection object
:rtype: Connection

:raises ConnectionError: If connection cannot be established
"""

Какой стиль выбрать? Это зависит от нескольких факторов:

  • Google style обеспечивает хороший баланс между читаемостью и информативностью
  • NumPy style предпочтителен для научных проектов с математическими формулами
  • reStructuredText лучше интегрируется с инструментами Sphinx

Наталья Петрова, руководитель отдела обеспечения качества кода

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

Мы провели голосование и выбрали Google style как наиболее интуитивно понятный. Затем настроили линтеры и внедрили автоматическую проверку при коммитах. Результат превзошёл ожидания: время на ревью сократилось на 40%, а количество вопросов между разработчиками уменьшилось почти на 70%. Главное, что мы вынесли из этого опыта: важен не столько выбор конкретного стиля, сколько его последовательное применение во всей кодовой базе.

PEP 8: правила оформления заголовков функций и классов

Если PEP 257 регламентирует стандарты документирования, то PEP 8 — это руководство по стилю кодирования Python, включающее правила именования и оформления заголовков функций, классов и других элементов кода. Эти стандарты неразрывно связаны с docstring, формируя полноценный профессиональный подход к разработке. 🛠️

Основные правила PEP 8 для заголовков функций и классов:

  • Имена функций: Используйте snake_case (слова в нижнем регистре, разделённые подчёркиваниями)
  • Имена классов: Используйте CamelCase (каждое слово с заглавной буквы, без разделителей)
  • Имена констант: Используйте UPPERSNAKECASE (все заглавные буквы, разделённые подчёркиваниями)
  • Приватные методы/атрибуты: Начинайте с одного подчёркивания (methodname)
  • "Очень приватные" методы/атрибуты: Начинайте с двух подчёркиваний (_methodname)
  • Магические методы: Окружайте двумя подчёркиваниями с обеих сторон (init)

Вот несколько примеров правильного именования по PEP 8:

Python
Скопировать код
# Функции
def calculate_average(numbers):
"""Return the average of a list of numbers."""
return sum(numbers) / len(numbers)

# Классы
class DatabaseConnection:
"""Class for managing database connections."""

def __init__(self, host, port):
"""Initialize connection with host and port."""
self.host = host
self.port = port

def _validate_credentials(self):
"""Internal method to validate credentials."""
pass

def __execute_raw_query(self, query):
"""Very private method for executing raw SQL queries."""
pass

# Константы
MAX_CONNECTION_ATTEMPTS = 3
DEFAULT_TIMEOUT = 30

Помимо именования, PEP 8 регламентирует и другие аспекты оформления заголовков:

  • Расположение импортов: стандартная библиотека, сторонние библиотеки, локальные импорты — с пустыми строками между группами
  • Количество пробелов: 4 пробела для отступов, без табуляций
  • Максимальная длина строки: 79 символов для кода, 72 для docstring и комментариев
  • Пустые строки: 2 между классами и функциями верхнего уровня, 1 между методами внутри класса

Соблюдение PEP 8 не просто делает код "красивым" — оно значительно упрощает чтение и понимание кода другими разработчиками, что критически важно в командных проектах.

Инструменты автоматизации проверки docstring-стандартов

Помнить все правила PEP 8 и PEP 257 — задача не из легких даже для опытного разработчика. К счастью, в экосистеме Python существует множество инструментов, которые автоматизируют проверку соответствия кода стандартам и помогают поддерживать высокое качество документации. 🤖

Основные инструменты для проверки docstring и форматирования кода:

  • pylint — один из самых всеобъемлющих инструментов для статического анализа, который проверяет как соответствие PEP 8, так и наличие docstring
  • flake8 — объединяет функциональность PyFlakes, pycodestyle и McCabe для комплексной проверки кода
  • pydocstyle — специализированный инструмент для проверки соответствия docstring стандарту PEP 257
  • black — бескомпромиссный форматтер кода, который автоматически приводит код к единому стилю
  • docformatter — инструмент для автоматического форматирования docstring
  • interrogate — проверяет уровень покрытия кода документацией

Пример настройки pre-commit хука для автоматизации проверки при коммите:

yaml
Скопировать код
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/pydocstyle
rev: 6.3.0
hooks:
- id: pydocstyle
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/myint/docformatter
rev: v1.7.5
hooks:
- id: docformatter
- repo: https://github.com/econchick/interrogate
rev: 1.5.0
hooks:
- id: interrogate
args: [-vv, -i, --fail-under=80]

Интеграция этих инструментов в процесс разработки даёт множество преимуществ:

  • Автоматизация рутинных проверок экономит время разработчиков
  • Раннее обнаружение несоответствий стандартам предотвращает накопление технического долга
  • Единообразие кода и документации упрощает поддержку проекта
  • Новые участники команды быстрее адаптируются к принятым стандартам

Для интеграции этих инструментов с популярными IDE:

  • PyCharm: Встроенная поддержка PEP 8 и возможность установки плагинов для других инструментов
  • VSCode: Расширения Python и Python Docstring Generator обеспечивают поддержку стандартов и автоматическое создание docstring
  • Jupyter Notebook: Расширение nbqa позволяет запускать инструменты проверки кода на ячейках Jupyter

Наиболее эффективный подход — настроить проверку на трёх уровнях:

  1. Локально: Интеграция с IDE для мгновенной обратной связи
  2. При коммите: Pre-commit хуки для предотвращения коммитов с нарушениями
  3. В CI/CD: Автоматизированные проверки при Pull Request и деплое

Качественно документированный код — это не роскошь, а необходимость в профессиональной разработке. Следование стандартам PEP 8 и PEP 257 при оформлении заголовков и docstring в Python существенно сокращает время на понимание кода, облегчает работу в команде и снижает количество ошибок. Внедрение автоматизированных инструментов проверки позволяет сделать этот процесс естественной частью рабочего потока. Помните: лучший код — это не только тот, который работает сегодня, но и тот, который будет понятен и через год.

Загрузка...