Документирование кода в Python. PEP 257

Документирование кода в python — достаточно важный аспект, ведь от нее порой зависит читаемость и быстрота понимания вашего кода, как другими людьми, так и вами через полгода.
PEP 257 описывает соглашения, связанные со строками документации python, рассказывает о том, как нужно документировать python код.
Цель этого PEP — стандартизировать структуру строк документации: что они должны в себя включать, и как это написать (не касаясь вопроса синтаксиса строк документации). Этот PEP описывает соглашения, а не правила или синтаксис.
При нарушении этих соглашений, самое худшее, чего можно ожидать — некоторых неодобрительных взглядов. Но некоторые программы (например, docutils), знают о соглашениях, поэтому следование им даст вам лучшие результаты.
Что такое строки документации?
Строки документации — строковые литералы, которые являются первым оператором в модуле, функции, классе или определении метода. Такая строка документации становится специальным атрибутом __doc__ этого объекта.
Все модули должны, как правило, иметь строки документации, и все функции и классы, экспортируемые модулем также должны иметь строки документации. Публичные методы (в том числе __init__) также должны иметь строки документации. Пакет модулей может быть документирован в __init__.py.
Для согласованности, всегда используйте «»»triple double quotes»»» для строк документации. Используйте r»»»raw triple double quotes»»», если вы будете использовать обратную косую черту в строке документации.
Существует две формы строк документации: однострочная и многострочная.
Однострочные строки документации
Однострочники предназначены для действительно очевидных случаев. Они должны умещаться на одной строке. Например:
Используйте тройные кавычки, даже если документация умещается на одной строке. Потом будет проще её дополнить.
Закрывающие кавычки на той же строке. Это смотрится лучше.
Нет пустых строк перед или после документации.
Однострочная строка документации не должна быть «подписью» параметров функции / метода (которые могут быть получены с помощью интроспекции). Не делайте:
list"""
Этот тип строк документации подходит только для C функций (таких, как встроенные модули), где интроспекция не представляется возможной. Тем не менее, возвращаемое значение не может быть определено путем интроспекции. Предпочтительный вариант для такой строки документации будет что-то вроде:
(Конечно, «Do X» следует заменить полезным описанием!)
Многострочные строки документации
Многострочные строки документации состоят из однострочной строки документации с последующей пустой строкой, а затем более подробным описанием. Первая строка может быть использована автоматическими средствами индексации, поэтому важно, чтобы она находилась на одной строке и была отделена от остальной документации пустой строкой. Первая строка может быть на той же строке, где и открывающие кавычки, или на следующей строке. Вся документация должна иметь такой же отступ, как кавычки на первой строке (см. пример ниже).
Вставляйте пустую строку до и после всех строк документации (однострочных или многострочных), которые документируют класс — вообще говоря, методы класса разделены друг от друга одной пустой строкой, а строка документации должна быть смещена от первого метода пустой строкой; для симметрии, поставьте пустую строку между заголовком класса и строкой документации. Строки документации функций и методов, как правило, не имеют этого требования.
Строки документации скрипта (самостоятельной программы) должны быть доступны в качестве «сообщения по использованию», напечатанной, когда программа вызывается с некорректными или отсутствующими аргументами (или, возможно, с опцией «-h», для помощи). Такая строка документации должна документировать функции программы и синтаксис командной строки, переменные окружения и файлы. Сообщение по использованию может быть довольно сложным (несколько экранов) и должно быть достаточным для нового пользователя для использования программы должным образом, а также полный справочник со всеми вариантами и аргументами для искушенного пользователя.
Строки документации модуля должны, как правило, перечислять классы, исключения, функции (и любые другие объекты), которые экспортируются модулем, с краткими пояснениями (в одну строчку) каждого из них. (Эти строки, как правило, дают меньше деталей, чем первая строка документации к объекту). Строки документации пакета модулей (т.е. строка документации в __init__.py) также должны включать модули и подпакеты.
Строки документации функции или метода должны обобщить его поведение и документировать свои аргументы, возвращаемые значения, побочные эффекты, исключения, дополнительные аргументы, именованные аргументы, и ограничения на вызов функции.
Строки документации класса обобщают его поведение и перечисляют открытые методы и переменные экземпляра. Если класс предназначен для подклассов, и имеет дополнительный интерфейс для подклассов, этот интерфейс должен быть указан отдельно (в строке документации). Конструктор класса должен быть задокументирован в документации метода __init__. Отдельные методы должны иметь свои строки документации.
Если класс — подкласс другого класса, и его поведение в основном унаследовано от этого класса, строки документации должны отмечать это и обобщить различия. Используйте глагол «override», чтобы указать, что метод подкласса заменяет метод суперкласса и не вызывает его; используйте глагол «extend», чтобы указать, что метод подкласса вызывает метод суперкласса (в дополнение к собственному поведению).
И, напоследок, пример:
А ещё больше примеров можно посмотреть в стандартной библиотеке python (например, в папке Lib вашего интерпретатора python).
Для вставки кода на Python в комментарий заключайте его в теги
Строки документации в Python. Документирование модуля, класса, методов
Поскольку в языках программирования, в том числе Python, существует большое количество встроенных и предоставляемых третьими сторонами модулей, то помнить их все, в том числе их функционал, невозможно. Поэтому важно документировать код. Под документированием понимаются не комментарии, а так называемые строки документации, которые принято добавлять в начало модуля, класса, метода или функции.
Основное назначение комментариев – пояснить что делает код, как он работает. Основное назначение строк документации – кратко описать в целом для чего предназначен объект, какие аргументы принимает, и что возвращает.

-->
В исходном коде Python строки документации заключаются в тройные кавычки и пишутся сразу под заголовком объекта. Пример документированного модуля:
"""Модуль содержит классы плоских фигур.""" from math import pi, pow class Rectangle: """Класс Прямоугольник.""" def __init__(self, a, b): """Конструктор принимает длину и ширину.""" self.w = a self.h = b def square(self): """Метод для вычисления площади.""" return round(self.w * self.h, 2) def perimeter(self): """Метод для вычисления периметра""" return 2 * (self.w + self.h) class Circle: """Класс Круг.""" def __init__(self, radius): """Конструктор принимает радиус.""" self.r = radius def square(self): """Метод для вычисления площади круга.""" return round(pi * pow(self.r, 2), 2) def length(self): """Метод для вычисления длины окружности.""" return round(2 * pi * self.r)
Извлекать строки документации можно двумя способами:
- Через встроенный для каждого объекта атрибут-переменную __doc__ .
- С помощью встроенной в Python функции help , которая запускает интерактивную справочную систему.
>>> import planimetry >>> planimetry.Rectangle.__doc__ 'Класс Прямоугольник.' >>> print(planimetry.__doc__) Модуль содержит классы плоских фигур.
Если дать команду help(planimetry) , то будут выведены все строки документации модуля в структурированном виде. Однако можно "заказывать" справку по отдельным объектам:
>>> help(planimetry.Circle.length) Help on function length in module geometry.planimetry: length(self) Метод для вычисления длины окружности.
Выход из справки осуществляется с помощью клавиши q .
В Python документированы все встроенные объекты и модули библиотеки.
>>> print(str.__doc__) str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
>>> import math >>> print(math.trunc.__doc__) Truncates the Real x to the nearest Integral toward 0. Uses the __trunc__ magic method. >>>
Таким образом, если вам надо узнать, для чего предназначена та или иная функция, и как она работает, это всегда можно сделать, не выходя из интерпретатора Python. Перечень атрибутов модуля или объекта можно посмотреть с помощью встроенной функции dir() .
Следует отметить, документирование модулей принято выполнять на английском языке. Многие проекты имеют открытый код, выкладываются в Веб, их смотрят и дорабатывают программисты из разных стран. Использование одного языка позволяет им понимать друг друга. Поэтому профессиональный программист должен владеть английским хотя бы на начальном уровне. Google Translate – тоже вариант.
Практическая работа
Выполните полное документирование модуля, созданного в практической работе прошлого урока.
Курс с примерами решений практических работ:
pdf-версия
X Скрыть Наверх
Объектно-ориентированное программирование на Python
Как применять и декораторы, и документацию в Python
Декораторы в Питоне конфликтуют с функцией документации help — если применить декоратор, вывод функции help изменится. Чтобы увидеть, пишем простой декоратор:
И 2 функции, с и без декоратора:
Help on function x: >>> help(x) x(c, d) Это X >>> help(y) Help on function z: z(*args, **kwargs)
Вместо y мы видим описание внутренней функции декоратора.
Если вы делаете свой модуль и хотите снова использовать его через некоторое время, то внутренняя документация будет очень полезной — чтобы узнать, как вызвать конкретную функцию, не надо будет читать исходный код модуля. Но если нужны декораторы, придётся искать какое-то решение…
У функций есть свойства func_doc, func_name, которые, в принципе, можно установить принудительно:
- def deco(fn):
- def z( * args, ** kwargs):
- return fn( * args, ** kwargs)
- z.func_doc = fn.func_doc
- z.func_name = fn.func_name
- return z
- @deco
- def y(a, b = 20 ):
- """Это Y"""
- pass
>>> help(y) Help on function y: y(*args, **kwargs) # а должно быть (a, b = 20) Это Y
Но список аргументов всё равно остался от внутренней функции. (Ответ на замечание читателя kmike: декоратор functools.wraps делает то же самое с тем же результатом)
Есть 2 решения: «чистое» в виде модуля и «грязное» в виде хака от Алекса Мартелли:
Модуль decorator
- from decorator import decorator
- @decorator
- def deco(fn):
- def z( * args, ** kwargs):
- return fn( * args, ** kwargs)
- return z
- @deco
- def y(a, b = 20 ):
- pass
>>> help(y) Help on function y: y(a, b = 20)
Хак Алекса Мартелли
Суть хака в том, чтобы записать все декорируемые функции в массив lookaside, а функцию inspect.getargspec (которая выдаёт данные о функции для help) заменяем другой, которая выдаёт записанные в lookaside данные, либо вызывает исходную getargspec.
- import functools, inspect
- realgas = inspect .getargspec
- lookaside = dict ()
- def fakegas(f):
- if f in lookaside:
- return lookaside[f]
- return realgas(f)
- inspect .getargspec = fakegas
- def deco(fn):
- @functools.wraps(fn)
- def z( * args, ** kwargs):
- return fn( * args, ** kwargs)
- lookaside[z] = realgas(fn) # обратите внимание, что
- return z
- @deco
- def x(a, b= 23 ):
- """Это X"""
- return a + b
help(x) Help on function x in module __main__: x(a, b=23) Some doc for x.
Как вызвать и использовать документацию python

Python обладает великолепной документацией и предоставляет удобные способы для работы с ней: от официального сайта до встроенной справочной системы.
Работа с документацией является одной из важных составляющих деятельности разработчика. И это не только чтение документации к библиотекам и комментариев в коде, но и документирование собственного кода, а также поддержание его в актуальном состоянии. Качественно задокументированный код во многих случаях упрощает его поддержание и сокращает время на «вхождение» новых сотрудников в проект. Если же речь идет об изучении нового языка программирования, качество документации и поддержка сообщества могут сыграть решающую роль в освоении материала и снизить порог вхождения.
Документация к языку программирования Python обладает всеми качествами, которые отличают «хорошую» документацию от «плохой». Тем не менее, новички часто сталкиваются с рядом вопросов. Как быстро найти информацию о классе или функции? Как самому писать документацию к коду? Какие инструменты можно использовать при документировании кода? На эти вопросы мы и постараемся ответить в статье.
Основной источник информации о Python
Безусловно, основным, наиболее полным и актуальным источником информации о Python является сайт c официальной документацией. Главная страница сайта предоставляет удобную навигацию по разделам.
Важные разделы сайта (полезно начинающим программистам):
- Setup and Usage — содержит информацию об установке и настройке Python на разных платформах;
- Tutorial — учебное пособие для новичков, с которого и рекомендуется начинать свой путь в мир Python;
- Library Reference — подробное описание стандартной библиотеки Python;
- Python HOWTO — различные руководства по конкретным темам;
- Language Reference — раздел для тех кто, хочет знать подробности реализации СPython.
Поиск по сайту с документацией
Для поиска по сайту имеются: окно быстрого поиска по ключевым словам и таблицы с индексами для поиска по названию модуля (класса, метода, переменной). Важно: Python динамично развивается, постоянно добавляются новые возможности и функционал. Если вы хотите работать с актуальной документацией — выберите необходимую вам версию Python в выпадающем меню в шапке сайта.
Создатели Python предусмотрели возможность установить документацию локально на компьютере. Для этого необходимо перейти на страницу загрузки, выбрать версию Python, формат файлов (доступны pdf, epub, html, txt) и способ архивирования. После скачивания и распаковки архива, вы можете пользоваться документацией в полном объеме.
Встроенная справочная система
Чтение объемного справочного руководства полезно на этапе изучения языка. При работе с кодом чаще возникает необходимость получить небольшую справку о работе той или иной функции, получаемых аргументах, или о наличии у класса атрибутов и методов. В таких случаях информация из официальной документации, как правило, избыточна, а поиск по ней может может занять значительное время. В Python для таких случаев существует встроенная справочная система, позволяющая быстро получить краткую справку об объекте.
Небольшое уточнение: поскольку в Python все является объектом, в том числе методы и классы, далее мы будем часто употреблять термин «объект» применительно к целям получения информации.
Доступ к встроенной справочной системе осуществляется с помощью функции help . Для получения справки по тому или иному объекту необходимо в интерпретаторе Python вызвать функцию help , а в качестве аргумента передать сам объект или строку с названием объекта.

В приведенном выше примере, мы вызвали справку по функции ord . В тексте сообщения содержится информация о том, что делает функция и к какому модулю она относится.
Теперь попробуем получить информацию о модуле стандартной библиотеки os .

Почему вызов функции завершился выбросом исключения? Ведь модуль os входит в стандартную библиотеку и маловероятно, что справочная информация по нему не была включена.
Docstring
Чтобы ответить на этот вопрос, давайте разберемся, где хранится справочная информация и как работает функция help . Как уже говорилось выше, все в Python является объектом. Все объекты в Python имеют специальный атрибут __doc__ , предназначенный для хранения строки документации — docstring. Вот как определено понятие docstring в официальной документации: «Docstring — строковый литерал, который встречается как первый оператор в определении модуля, функции, класса или метода. Такой docstring становится специальным атрибутом __doc__ этого объекта».
Посмотрим, что хранится в атрибуте __doc__ объекта ord.

Размещение справки об объекте в исходном коде самого объекта позволяет элегантно решить вопрос хранения информации и доступа к ней. Функция help при передаче ей в качестве аргумента объекта для получения информации о нем, обращается к атрибуту __doc__ этого объекта. Поскольку модуль os не импортирован, он отсутствует в глобальной области видимости и не доступен при вызове функции help . Именно по этой причине мы получаем ошибку. Для решения проблемы достаточно импортировать модуль. Есть еще один способ избежать ошибки и не связанный с импортом объекта — передать в качестве аргумента в функцию help строку с именем объекта.

В этом случае функция help для получения информации будет использовать модуль стандартной библиотеки pydoc , который выполнит импорт объекта и генерацию справки.
Посмотрим на исходный код модуля os и убедимся в том, что docstring и содержимое атрибута os . __doc__ совпадают. Из приведенного кода видно, как определяются в коде docstring. Строки документации заключаются в тройные кавычки и пишутся сразу под заголовком объекта.
Вы уже заметили, что вывод функции help отличается от вывода, полученного через обращение к атрибуту __doc__ объекта. Он более информативен и выводит информацию в виде форматированного текста. У функции help есть еще одна особенность, повышающая удобство работы со справочной системой. При вызове help без аргументов запускается интерактивный режим справочной системы. Для получения справки в нем достаточно набрать только название интересующего нас объекта. Запустив интерактивный режим в отдельном терминале, мы получаем удобный инструмент для работы с документацией.
Встроенная справочная система
Стандартная библиотека Python весьма обширна и содержит большое количество модулей. Помнить их все, в том числе и заложенный функционал, невозможно. Что делать, если мы не помним (не знаем) название модуля, класса или функции? Ниже приведены несколько примеров, помогающих в таких ситуациях.
Получение списка доступных модулей:

Получение ключевых слов:

Получение списка названий встроенных функций:

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

Как задокументировать собственный код?
Теперь, когда мы знаем о docstring и работе функции help , мы можем задокументировать свой код. В качестве примера возьмем скрипт factorial. py:

Добавим docstring.

Убедимся в наличии документации по модулю factorial :

Вызов help (factorial) вернет справку:

При создании документации к коду стоит придерживаться правил и рекомендаций, описанных в PEP257 и PEP8. Ссылки на эти документы приведены в конце статьи.
О библиотеке pydoc
Мы уже упоминали модуль стандартной библиотеки pydoc . Он автоматически генерирует документацию из модулей Python. Документация может быть представлена в виде страниц текста на консоли, отображаться в браузере или сохраняться в HTML-файлах.
Команда pydoc позволяет вывести текст справки прямо в терминале (не интерпретаторе Python):

Для создания документации в виде HTML-страниц используется ключ -w . Это позволяет организовать хранение документации отдельно от кода.

Для поиска по docstring модулей используется ключ -k . В качестве аргумента в этом случае передается ключевое слово. В результате будут выведены названия всех модулей в docstring которых встречается ключевое слово.

Обратим ваше внимание на одну особенность поиска по документации при использовании ключа -k . Поиск производится только по первым строкам документации модулей. Тем не менее, данный функционал может быть весьма полезным в некоторых случаях.
Для любителей работать в браузере, предусмотрена возможность запуска HTTP-сервера документации, который будет доступен по порту, указанному после ключа -p .

В третьей версии Python для управления сервером добавлена пара команд: b — открытие страницы документации в браузере, q — завершения работы сервера. При вызове команды pydoc3 с ключом -b произойдет запуск сервера и автоматическое открытие страницы в браузере. В документацию также будут включены модули, расположенные в директории из которой был запущен сервер.
Соблюдение соглашений
При документировании кода важно соблюдать принятые в языке программирования соглашения. Для решения этих задач существуют различные инструменты. В этой статье мы становимся на одном из них — модуле pydocstyle .
Модуль pydocstyle — это инструмент статического анализа для проверки соответствия docstring соглашениям, принятым в Python. Установка модуля осуществляется с помощью менеджера пакетов pip: