PEP 257 - Соглашения для строк документации (docstrings)

Аннотация

Этот PEP описывает семантику и соглашения, связанные со строками документации Python.

Обоснование

Целью данного PEP является стандартизация структуры строк документации: что они должны содержать и что они должны объяснять (не затрагивая синтаксис разметки внутри строк документации). PEP содержит соглашения, а не законы или синтаксис.

“Универсальное соглашение обеспечивает удобство сопровождения, ясность, последовательность, а также закладывает основу для хороших привычек программирования. Что оно не делает, так это настаивает на том, чтобы вы ему следовали против своей воли. Это Python!”

- Тим Питерс, comp.lang.python, 2001-06-16

Если вы нарушите эти соглашения, самое худшее, что вас ждет — несколько неодобрительных взглядов. Однако некоторые программы (например, системы обработки строк документации, такие как Docutils, упомянутые в PEP 256 и PEP 258) используют эти соглашения. Поэтому их соблюдение приведет к лучшим результатам.

Спецификация

Что такое строки документации?

Строки документации — это строковые литералы, расположенные первыми внутри тела модуля, функции, класса или метода. Такая строка документации становится значением специального атрибута __doc__ соответствующего объекта.

Все модули должны, как правило, иметь строки документации, и все функции и классы, экспортируемые модулем также должны иметь строки документации. Публичные методы (в том числе __init__) также должны иметь строки документации. Пакет модулей может быть документирован в __init__.py в директории пакета.

Строковые литералы, используемые в других местах кода Python, также могут выполнять функцию документации. Однако такие строки не обрабатываются компилятором байткода Python и не доступны как атрибуты __doc__. Программные инструменты могут извлекать два дополнительных типа документации:

  1. Строковые литералы, встречающиеся сразу после простого присваивания на верхнем уровне модуля, класса или метода __init__, называются "строкой документации атрибута".
  2. Строковые литералы, встречающиеся сразу после другой строки документации, называются "дополнительной строкой документации".

Подробнее о них можно узнать в PEP 258, “Docutils Design Specification”.

Для согласованности, всегда используйте """три двойные кавычки""" для строк документации. Используйте r"""сырую строку три двойные кавычки""", если вы будете использовать обратную косую черту в строке документации.

Существует две формы строк документации: однострочная и многострочная.

Однострочные строки документации

Однострочники предназначены для действительно очевидных случаев. Они должны умещаться на одной строке. Например:

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
  • Используйте тройные кавычки, даже если документация умещается на одной строке. Это облегчает дальнейшее расширение документации.

  • Закрывающие кавычки располагаются на той же строке, что и содержимое.

  • Нет пустых строк перед или после строки документации, сразу идет код.

  • Строка документации - это фраза, заканчивающаяся точкой. Она поясняет действие функции или метода в императивном тоне ("Сделай это", "Верни то"), а не как описание; например, не пишите "Возвращает имя пути ...".

    Значение фразы "императивный тон" в английском языке в оригинале поясняется на примере словосочетаний "Return pathname" и "Returns pathname". PEP-257 предписывает придерживаться первого стиля, потому что он более строгий.

  • Однострочная строка документации не должна быть "подписью" параметров функции / метода (которые могут быть получены с помощью интроспекции). Не делайте:

    def function(a, b):
        """function(a, b) -> list"""
    

    Этот тип строк документации подходит только для C функций (таких, как встроенные модули), где интроспекция не представляется возможной. Тем не менее, возвращаемое значение не может быть определено путем интроспекции. Предпочтительный вариант для такой строки документации будет что-то вроде:

    def function(a, b):
        """Do X and return a list."""
    

    (Конечно, "Do X" следует заменить полезным описанием!)

Многострочные строки документации

Многострочные строки документации состоят из сводной строки (summary line), имеющей такую же структуру, как и однострочная строка документации. Она должна быть отделена от последующего текста пустой строкой, а затем следует более подробное описание.

Первая строка может быть использована автоматическими средствами индексации, поэтому важно, чтобы она занимала ровно одну строку и была отделена от остальной документации пустой строкой. Первая строка может быть на той же строке, где и открывающие кавычки, или на следующей строке. Вся документация должна иметь такой же отступ, как кавычки на первой строке (см. пример ниже).

Вставляйте пустую строку до и после всех строк документации (однострочных или многострочных), которые документируют класс - вообще говоря, методы класса разделены друг от друга одной пустой строкой, а строка документации должна быть смещена от первого метода пустой строкой; для симметрии, поставьте пустую строку между заголовком класса и строкой документации.

Строки документации скрипта (самостоятельной программы) должны быть доступны в качестве "сообщения по использованию", напечатанной, когда программа вызывается с некорректными или отсутствующими аргументами (или, возможно, с опцией "-h", для помощи). Такая строка документации должна документировать функции программы и синтаксис командной строки, переменные окружения и файлы. Сообщение по использованию может быть довольно сложным (несколько экранов) и должно быть достаточным для нового пользователя для использования программы должным образом, а также полный справочник со всеми вариантами и аргументами для искушенного пользователя.

Строки документации модуля должны, как правило, перечислять классы, исключения, функции (и любые другие объекты), которые экспортируются модулем, с краткими пояснениями (в одну строчку) каждого из них. (Эти строки, как правило, дают меньше деталей, чем первая строка документации к объекту). Строки документации пакета модулей (т.е. строка документации в __init__.py) также должны включать модули и подпакеты.

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

Строки документации класса обобщают его поведение и перечисляют открытые методы и переменные экземпляра. Если класс предназначен для подклассов, и имеет дополнительный интерфейс для подклассов, этот интерфейс должен быть указан отдельно (в строке документации). Конструктор класса должен быть задокументирован в документации метода __init__. Отдельные методы должны иметь свои строки документации.

Если класс - подкласс другого класса, и его поведение в основном унаследовано от этого класса, строки документации должны отмечать это и обобщить различия. Используйте глагол "override", чтобы указать, что метод подкласса заменяет метод суперкласса и не вызывает его; используйте глагол "extend", чтобы указать, что метод подкласса вызывает метод суперкласса (в дополнение к собственному поведению).

Не используйте соглашение Emacs, согласно которому аргументы функций или методов указываются в верхнем регистре в тексте. Python чувствителен к регистру, а имена аргументов могут быть использованы в качестве именованных аргументов, поэтому в строке документации должны быть указаны правильные имена аргументов. Лучше всего перечислять каждый аргумент в отдельной строке. Например:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)
    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Если только вся строка документа не помещается в одной строке, поместите закрывающие кавычки в отдельной строке.

Обработка отступов строк документации

Инструменты обработки строк документаци должны удалять одинаковое количество отступов, равное минимальному отступу всех не пустых строк, начиная со второй.

Любые отступы в первой строке документации несущественны и будут удалены. Относительный отступ более поздних строк в строке документа сохраняется. Пустые строки должны быть удалены из начала и конца строки документа.

Поскольку код гораздо точнее слов, здесь приведена реализация алгоритма:

def trim(docstring):
    if not docstring:
        return ''
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = docstring.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxsize
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxsize:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

Документация в следующем примере содержит два символа новой строки и поэтому имеет длину равную трём. Первая и последняя строки пусты:

def foo():
    """
    This is the second line of the docstring.
    """

Проиллюстрируем:

>>> print repr(foo.__doc__)
'\n    This is the second line of the docstring.\n    '
>>> foo.__doc__.splitlines()
['', '    This is the second line of the docstring.', '    ']
>>> trim(foo.__doc__)
'This is the second line of the docstring.'

Однако после обработки следующие строки документации будут эквивалентны:

def foo():
    """A multi-line
    docstring.
    """
def bar():
    """
    A multi-line
    docstring.
    """

Вы можете также использовать модуль inspect и его метод cleandoc() для обработки строк документации.

inspect.cleandoc(foo.__doc__)

Популярные статьи

Объект range

Изучение объекта range в Python. Создание последовательностей чисел, использование в циклах и примеры применения.

PEP 257 - соглашения для строк документации (docstrings)

Целью данного PEP является стандартизация структуры строк документации: что они должны содержать и что должны объяснять.

Бесплатные курсы Python

Обзор бесплатных курсов, обучающих видео по языку программирования Python