Форматы docstring: Google Style, NumPy, reStructuredText
В прошлом уроке мы узнали, что такое docstring. Теперь разберёмся, как его правильно оформлять. В Python существует три главных формата — каждый со своими правилами записи. Разберём все три на одном и том же примере и решим, какой выбрать.
🤔 Зачем нужны форматы — разве тройных кавычек не достаточно?
Python требует только одного: docstring должен начинаться с тройных кавычек и стоять сразу после объявления функции или класса. Никаких правил о том, как именно писать содержимое внутри — в стандарте нет.
На практике это привело к тому, что каждый писал docstring по-своему. Параметры кто-то описывал через тире, кто-то в скобках, кто-то вообще не описывал. Чтение таких docstring'ов превращалось в квест.
Поэтому сообщество выработало соглашения — единые правила оформления. Главных три:
🟢
Google Style
Лаконичный и читаемый. Самый популярный в современных проектах. Рекомендован для большинства случаев.
🔵
NumPy Style
Более развёрнутый и структурированный. Стандарт в научных библиотеках: NumPy, SciPy, pandas.
🟡
reStructuredText
Официальный формат PEP 287. Используется в Sphinx для генерации документации. Многословен, но машинно читаем.
💡 Самое важное правило: не важно, какой формат вы выберете — важно использовать один и тот же формат во всём проекте. Смесь форматов в одном проекте — признак хаоса в команде.
🧪 Наша подопытная функция
Чтобы честно сравнить все три формата, мы возьмём одну и ту же функцию и запишем её docstring тремя способами. Вот наша функция:
def calculate_bmi(weight, height):
if height <= 0:
raise ValueError("Рост должен быть больше нуля")
bmi = weight / (height ** 2)
return round(bmi, 2)
📋 Что делает эта функция:
- Принимает weight — вес человека в килограммах (число с плавающей точкой)
- Принимает height — рост в метрах (число с плавающей точкой)
- Вычисляет ИМТ (индекс массы тела) по формуле: вес / рост²
- Возвращает результат, округлённый до 2 знаков после запятой
- Вызывает ValueError, если рост равен нулю или отрицательный
🟢 Формат Google Style
Google Style был разработан и популяризован компанией Google для внутренних Python-проектов. Сегодня это самый распространённый формат в современных open-source библиотеках и продуктовых командах.
Главная идея: секции обозначаются заголовком с двоеточием (Args:, Returns:, Raises:), а содержимое каждой секции пишется с отступом в 4 пробела.
def calculate_bmi(weight, height):
"""
Вычисляет индекс массы тела (ИМТ) человека.
Индекс массы тела — это число, которое показывает,
соответствует ли вес человека его росту. Вычисляется
по формуле: weight / height ** 2.
Args:
weight (float): Вес человека в килограммах.
Должен быть положительным числом.
height (float): Рост человека в метрах.
Должен быть больше нуля.
Returns:
float: ИМТ, округлённый до 2 знаков после запятой.
Raises:
ValueError: Если height равен нулю или отрицателен.
Example:
>>> calculate_bmi(70, 1.75)
22.86
>>> calculate_bmi(90, 1.80)
27.78
"""
if height <= 0:
raise ValueError("Рост должен быть больше нуля")
bmi = weight / (height ** 2)
return round(bmi, 2)
Разберём структуру по частям:
Первая строка
Краткое описание в одну строку. Отвечает на вопрос «что делает?». Заглавная буква, точка в конце.
Args:
Список параметров. Формат: имя (тип): описание. Если описание длинное — переносим на новую строку с двойным отступом.
Returns:
Описание возвращаемого значения. Формат: тип: описание.
Raises:
Исключения, которые может вызвать функция. Формат: ТипОшибки: когда возникает.
Example:
Примеры вызова функции в формате Python REPL (>>>). Показывает ожидаемый вывод.
✅ Плюсы Google Style
— Легко читается «глазами» — структура интуитивно понятна без знания формата
— Компактный: меньше символов на экране, не «раздувает» docstring
— Поддерживается популярными IDE (PyCharm, VS Code) и инструментом Napoleon для Sphinx
🔵 Формат NumPy Style
NumPy Style разработан командой NumPy — одной из важнейших научных библиотек Python. Его используют NumPy, SciPy, pandas, scikit-learn и другие инструменты для науки о данных.
Главная идея: каждая секция обозначается заголовком, а под заголовком проводится горизонтальная черта из дефисов такой же длины, как заголовок. Параметры описываются более развёрнуто — тип пишется не в скобках, а на следующей строке.
def calculate_bmi(weight, height):
"""
Вычисляет индекс массы тела (ИМТ) человека.
Индекс массы тела — это число, которое показывает,
соответствует ли вес человека его росту. Вычисляется
по формуле: weight / height ** 2.
Parameters
----------
weight : float
Вес человека в килограммах.
Должен быть положительным числом.
height : float
Рост человека в метрах.
Должен быть больше нуля.
Returns
-------
float
ИМТ, округлённый до 2 знаков после запятой.
Raises
------
ValueError
Если height равен нулю или отрицателен.
Examples
--------
>>> calculate_bmi(70, 1.75)
22.86
>>> calculate_bmi(90, 1.80)
27.78
"""
if height <= 0:
raise ValueError("Рост должен быть больше нуля")
bmi = weight / (height ** 2)
return round(bmi, 2)
Обратите внимание на ключевые отличия от Google Style:
- Секция называется
Parameters(а неArgs), и под ней идёт строка из дефисов:---------- - Тип параметра пишется через пробел после имени:
weight : float - Описание параметра — на следующей строке с отступом
- Секция возврата называется
Returns, тип на отдельной строке, описание — ниже - Секция исключений называется
Raises, тип на отдельной строке - Примеры — во множественном числе:
Examples
✅ Плюсы и ⚠️ минусы NumPy Style
✅ Очень чёткая структура — легко сканировать взглядом при большом числе параметров
✅ Стандарт в научном сообществе — если вы пишете для DS/ML, это привычный формат
⚠️ Более многословный — занимает больше места, чем Google Style
⚠️ Строки из дефисов приходится рисовать вручную и поддерживать их длину
🟡 Формат reStructuredText (Sphinx-style)
reStructuredText (сокращённо reST) — это язык разметки, созданный специально для документации Python. Именно его использует Sphinx — самая популярная система генерации документации. Официальный PEP 287 рекомендует reST как стандарт.
Главная идея: каждый элемент описывается отдельной директивой-тегом с двоеточиями: :param имя:, :type имя:, :return:, :rtype:, :raises ТипОшибки:. Никаких секций — каждый параметр описывается на своей строке.
def calculate_bmi(weight, height):
"""
Вычисляет индекс массы тела (ИМТ) человека.
Индекс массы тела — это число, которое показывает,
соответствует ли вес человека его росту. Вычисляется
по формуле: weight / height ** 2.
:param weight: Вес человека в килограммах.
:type weight: float
:param height: Рост человека в метрах. Должен быть больше нуля.
:type height: float
:return: ИМТ, округлённый до 2 знаков после запятой.
:rtype: float
:raises ValueError: Если height равен нулю или отрицателен.
Пример использования::
>>> calculate_bmi(70, 1.75)
22.86
"""
if height <= 0:
raise ValueError("Рост должен быть больше нуля")
bmi = weight / (height ** 2)
return round(bmi, 2)
Запомните эти теги — именно их распознаёт Sphinx и IDE:
:param имя:
Описание параметра функции. Один тег на каждый параметр.
:type имя:
Тип параметра. Идёт сразу после :param для того же параметра.
:return:
Описание возвращаемого значения.
:rtype:
Тип возвращаемого значения. Sphinx создаёт ссылку в документации.
:raises Тип:
Исключение и условие его возникновения.
✅ Плюсы и ⚠️ минусы reST
✅ Официальный стандарт Python — поддерживается Sphinx «из коробки»
✅ Машинно-читаемый — IDE и инструменты анализируют теги и дают подсказки
⚠️ Теги :param: / :type: выглядят многословно при чтении «глазами»
⚠️ При большом числе параметров docstring становится очень длинным
⚠️ Менее читаем для новичков без знания reST-разметки
⚖️ Сравнение форматов — таблица
Теперь посмотрим на три формата рядом, чтобы понять разницу наглядно.
| Критерий | Google Style | NumPy Style | reStructuredText |
|---|---|---|---|
| Читаемость | ⭐⭐⭐⭐⭐ Отличная | ⭐⭐⭐⭐ Хорошая | ⭐⭐⭐ Средняя |
| Компактность | ✅ Компактный | ⚠️ Многословный | ⚠️ Многословный |
| Поддержка Sphinx | ✅ Через Napoleon | ✅ Через Napoleon | ✅ Нативная |
| Популярность | 🔥 Очень высокая | 📊 В DS/ML сфере | 📘 Старые проекты |
| Порог входа | ✅ Низкий | ⚠️ Средний | ⚠️ Средний |
| Лучше всего для | Большинство проектов | Научные библиотеки | Sphinx-документация |
📐 Структура хорошего docstring — универсальный шаблон
Независимо от выбранного формата, структура хорошего docstring всегда следует одному и тому же порядку. Это порядок закреплён в PEP 257 и является общепринятой практикой:
Краткое описание (Summary line)
Одна строка. Что делает функция/метод. Начинается с глагола: «Вычисляет...», «Возвращает...», «Преобразует...». Без точки в конце необязательно, но принято с точкой.
Пустая строка
Обязательная пустая строка после краткого описания. Именно это отделяет summary от деталей. PEP 257 требует её явно.
Расширенное описание (опционально)
Если одной строки недостаточно — здесь поясняем детали: алгоритм, ограничения, особенности поведения. Для простых функций этого раздела может не быть.
Args / Parameters
Список всех параметров с типами и описанием. Каждый параметр с новой строки. Пропускается, если у функции нет параметров.
Returns
Тип и смысл возвращаемого значения. Пропускается для функций, возвращающих None.
Raises
Все исключения, которые может явно вызвать функция. Каждое с объяснением — при каком условии.
Examples
Примеры вызова. Часто самая полезная часть — читатель сразу видит «живой» код. Примеры также можно запустить через doctest.
🎯 Не нужно писать все секции всегда. Простой функции без параметров достаточно одной строки. Секция Raises нужна только если функция что-то вызывает. Ориентируйтесь на полезность: docstring должен отвечать на вопросы читателя, а не быть «заполненной бюрократической формой».
🏆 Какой формат выбрать? Наша рекомендация
Вопрос не в том, какой формат «правильный» — все три правильные. Вопрос в том, какой подходит вашей ситуации.
✅ Для большинства проектов: Google Style
Если вы пишете веб-сервис, утилиту, API, автоматизацию или любой «обычный» Python-проект — используйте Google Style. Он читается легче всего, требует минимум «шаблонного» текста и поддерживается всеми современными инструментами.
🔵 Для Data Science и научных библиотек: NumPy Style
Если ваш проект связан с анализом данных, машинным обучением, и вы работаете с экосистемой NumPy/pandas/scikit-learn — используйте NumPy Style. Ваши коллеги из этой сферы привыкли именно к нему.
🟡 Для библиотек с HTML-документацией: reStructuredText
Если вы разрабатываете публичную библиотеку и хотите генерировать красивую HTML-документацию через Sphinx без дополнительных расширений — reST подойдёт лучше всего.
🚫 Главное правило — один формат в проекте
Не смешивайте форматы в одном проекте. Если в одном файле Google Style, а в другом NumPy — это хаос. Договоритесь с командой заранее, зафиксируйте в README или CONTRIBUTING.md и придерживайтесь этого всегда.
📌 Быстрый справочник — ключевые секции
Шпаргалка: одни и те же элементы в трёх форматах.
# Параметры
# Google Style:
# Args:
# name (type): описание.
# NumPy Style:
# Parameters
# ----------
# name : type
# описание.
# reStructuredText:
# :param name: описание.
# :type name: type
# Возвращаемое значение
# Google Style:
# Returns:
# type: описание.
# NumPy Style:
# Returns
# -------
# type
# описание.
# reStructuredText:
# :return: описание.
# :rtype: type
# Исключения
# Google Style:
# Raises:
# ValueError: когда возникает.
# NumPy Style:
# Raises
# ------
# ValueError
# когда возникает.
# reStructuredText:
# :raises ValueError: когда возникает.
✅ Итоги урока
- Три главных формата: Google Style, NumPy Style и reStructuredText — каждый со своим синтаксисом секций.
- Google Style использует заголовки с двоеточием (
Args:,Returns:,Raises:) и отступы — лаконичный и читаемый. - NumPy Style использует заголовок и строку дефисов под ним, тип и описание параметра на отдельных строках — подробный и структурированный.
- reStructuredText использует теги-директивы (
:param:,:type:,:return:,:rtype:,:raises:) — официальный формат Sphinx. - Структура docstring: краткое описание → пустая строка → детали → Args → Returns → Raises → Examples.
- Рекомендация: для большинства проектов используйте Google Style — он популярнее всего и легче читается.
- Железное правило: один формат на весь проект. Смешивать форматы — недопустимо.
👉 В следующем уроке мы познакомимся с type hints — аннотациями типов в Python. Вы узнаете, как совмещать аннотации типов и docstring, чтобы ваш код был максимально понятным и помогал IDE находить ошибки ещё до запуска программы.