Как документировать метод с параметром (ами)?

139

Как документировать методы с параметрами, используя строки документации Python?

РЕДАКТИРОВАТЬ: PEP 257 дает этот пример:

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
    ...

Это соглашение используется большинством разработчиков Python?

Keyword arguments:
<parameter name> -- Definition (default value if any)

Я ожидал чего-то более формального, такого как

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

    @param: real The real part (default 0.0)
    @param: imag The imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Окружение : Python 2.7.1

Дэвид Андреолетти
источник
1
Вы читали PEP 257? python.org/dev/peps/pep-0257
NPE
1
Существует несколько «стандартов», но на практическом подходе, особенно если вам нравится что-то формальное, я бы порекомендовал sphinx . Его интеграция в Pycharm делает создание хорошо структурированных строк документации довольно безболезненным. ИМХО
Jojo

Ответы:

86

Основываясь на моем опыте, Numpy конвенция строки документации (PEP257 надстройка) являются наиболее широко распространенными следовали конвенции, которые также поддерживаются инструментами, такие , как сфинкс .

Один пример:

Parameters
----------
x : type
    Description of parameter `x`.
Владимир Келешев
источник
2
Это ближе к тому, что я ожидал. К сожалению, я выбрал простой PEP 257 и добавил свое собственное соглашение (за счет потери автоматически сгенерированной документации HTML / PDF). Однако в следующий раз я выберу это решение. Спасибо.
Дэвид Андреолетти
5
Когда я пытаюсь обработать вашу предложенную строку документации, Сфинкс жалуется SEVERE: Unexpected section title- знаете ли вы какой-нибудь способ сделать Сфинкса счастливее?
Брэндон Родс
@BrandonRhodes по этой ссылке рассказывается об использовании этих соглашений со Сфинксом: github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Владимир Келешев,
3
На самом деле до этого места не хватает Description. Я проверил пустую документацию, потому что сразу заметил и подумал: «Подождите секунду, почему это три пробела? Странно. Кто будет использовать три пробела?»
Зельфир Кальцталь
6
Возможно, это был лучший ответ в то время, когда был задан вопрос, но я думаю, что сейчас (в конце 2017 года) Сфинкс вышел победителем.
Алекс Л
120

Поскольку строки документации имеют произвольную форму, это действительно зависит от того, что вы используете для анализа кода для создания документации API.

Я бы порекомендовал ознакомиться с разметкой Sphinx , поскольку она широко используется и становится стандартом де-факто для документирования проектов Python, отчасти из-за отличного сервиса readthedocs.org . Чтобы перефразировать пример из документации Сфинкса в качестве сниппета Python:

def send_message(sender, recipient, message_body, priority=1):
   '''
   Send a message to a recipient

   :param str sender: The person sending the message
   :param str recipient: The recipient of the message
   :param str message_body: The body of the message
   :param priority: The priority of the message, can be a number 1-5
   :type priority: integer or None
   :return: the message id
   :rtype: int
   :raises ValueError: if the message_body exceeds 160 characters
   :raises TypeError: if the message_body is not a basestring
   '''

Эта разметка поддерживает перекрестные ссылки между документами и многое другое. Обратите внимание, что документация Sphinx использует (например), :py:attr:тогда как вы можете просто использовать :attr:при документировании из исходного кода.

Естественно, есть другие инструменты для документирования API. Есть более классический Doxygen, который использует \param команды, но они специально не предназначены для документирования кода Python, как Sphinx.

Обратите внимание, что здесь есть похожий вопрос с аналогичным ответом ...

anarcat
источник
9
Этот стиль используется автогенерацией комментариев PyCharm по умолчанию
Josiah Yoder
Как насчет синтаксиса составных типов, таких как списки вещей?
matanster
тогда это list.
Анаркат
33

Условные обозначения:

Инструменты:


Обновление: начиная с Python 3.5 вы можете использовать подсказки типов, которые представляют собой компактный машиночитаемый синтаксис:

from typing import Dict, Union

def foo(i: int, d: Dict[str, Union[str, int]]) -> int:
    """
    Explanation: this function takes two arguments: `i` and `d`.
    `i` is annotated simply as `int`. `d` is a dictionary with `str` keys
    and values that can be either `str` or `int`.

    The return type is `int`.

    """

Основным преимуществом этого синтаксиса является то, что он определяется языком и является однозначным, поэтому такие инструменты, как PyCharm, могут легко воспользоваться его преимуществами.

Якуб Розтоцил
источник
12
Хотя в настоящее время этот ответ пользуется наибольшим спросом, ни один из вышеперечисленных PEP не предоставляет соглашения для определения типов аргументов метода.
кориандр
11

Строки документа Python имеют произвольную форму , вы можете задокументировать их так, как вам нравится.

Примеры:

def mymethod(self, foo, bars):
    """
    Does neat stuff!
    Parameters:
      foo - a foo of type FooType to bar with.
      bars - The list of bars
    """

Теперь есть некоторые соглашения, но Python не применяет ни одного из них. Некоторые проекты имеют свои собственные соглашения. Некоторые инструменты для работы со строками документов также следуют определенным соглашениям.

nosklo
источник
8

Если вы планируете использовать Sphinx для документирования своего кода, он может создавать документы в формате HTML для ваших параметров с помощью функции «подписи». http://sphinx-doc.org/domains.html#signatures

Кайл Мед
источник
3

Основной поток, как уже указывалось в других ответах, вероятно, идет по пути Sphinx, чтобы вы могли использовать Sphinx для создания этих необычных документов позже.

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

def complex(  # Form a complex number
        real=0.0,  # the real part (default 0.0)
        imag=0.0  # the imaginary part (default 0.0)
        ):  # Returns a complex number.
    """Form a complex number.

    I may still use the mainstream docstring notation,
    if I foresee a need to use some other tools
    to generate an HTML online doc later
    """
    if imag == 0.0 and real == 0.0:
        return complex_zero
    other_code()

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

def foo(  # Note that how I use the parenthesis rather than backslash "\"
          # to natually break the function definition into multiple lines.
        a_very_long_parameter_name,
            # The "inline" text does not really have to be at same line,
            # when your parameter name is very long.
            # Besides, you can use this way to have multiple lines doc too.
            # The one extra level indentation here natually matches the
            # original Python indentation style.
            #
            # This parameter represents blah blah
            # blah blah
            # blah blah
        param_b,  # Some description about parameter B.
            # Some more description about parameter B.
            # As you probably noticed, the vertical alignment of pound sign
            # is less a concern IMHO, as long as your docs are intuitively
            # readable.
        last_param,  # As a side note, you can use an optional comma for
                     # your last parameter, as you can do in multi-line list
                     # or dict declaration.
        ):  # So this ending parenthesis occupying its own line provides a
            # perfect chance to use inline doc to document the return value,
            # despite of its unhappy face appearance. :)
    pass

Преимущества (как @ mark-horvath уже указывалось в другом комментарии):

  • Самое главное, что параметры и их документ всегда остаются вместе, что дает следующие преимущества:
  • Меньше ввода (не нужно повторять имя переменной)
  • Более простое обслуживание при смене / удалении переменной. После переименования какого-либо параметра никогда не будет какого-либо абзаца с документом-параметром.
  • и легче найти пропущенный комментарий.

Теперь некоторые могут подумать, что этот стиль выглядит «некрасиво». Но я бы сказал, «уродливый» - субъективное слово. Более нейтральный способ - сказать, что этот стиль не является мейнстримом, поэтому он может показаться вам менее знакомым и, следовательно, менее удобным. Опять же, «удобно» - это тоже субъективное слово. Но дело в том, что все преимущества, описанные выше, объективны. Вы не можете достичь их, если вы будете следовать стандартным путем.

Надеемся, что когда-нибудь в будущем появится инструмент для генерации документов, который также может использовать такой встроенный стиль. Это будет стимулировать принятие.

PS: Этот ответ вытекает из моего собственного предпочтения использовать встроенные комментарии всякий раз, когда я считаю нужным. Я использую тот же встроенный стиль, чтобы документировать словарь тоже.

RayLuo
источник
1

Основываясь на ответе на подсказки типа ( https://stackoverflow.com/a/9195565/2418922 ), который обеспечивает более структурированный способ документирования типов параметров, существует также структурированный способ документирования как типа, так и описания параметров:

def copy_net(
    infile: (str, 'The name of the file to send'),
    host: (str, 'The host to send the file to'),
    port: (int, 'The port to connect to')):

    pass

пример взят из: https://pypi.org/project/autocommand/

DreamFlasher
источник
1
Это официальный синтаксис? Это супер полезно, однако я не могу найти его в официальных документах / PEPs ...
Офри Равив
1
Я тоже хотел бы знать это, если есть PEP для этого.
DreamFlasher
-1

Строки документов полезны только в интерактивных средах, например, в оболочке Python. При документировании объектов, которые не будут использоваться в интерактивном режиме (например, внутренние объекты, обратные вызовы фреймворка), вы также можете использовать обычные комментарии. Вот стиль, который я использую для подвешивания комментариев с отступами к элементам, каждый на отдельной строке, чтобы вы знали, что комментарий применяется к:

def Recomputate \
  (
    TheRotaryGyrator,
      # the rotary gyrator to operate on
    Computrons,
      # the computrons to perform the recomputation with
    Forthwith,
      # whether to recomputate forthwith or at one's leisure
  ) :
  # recomputates the specified rotary gyrator with
  # the desired computrons.
  ...
#end Recomputate

Вы не можете делать такие вещи с помощью строк документации.

Лоуренс Д'Оливейро
источник
46
О, этот выглядит ужасно
Миша Акованцев
1
Некрасиво да? Интересная идея ... тоже да.
Дэвид
2
Встроенные комментарии к переменным очень разумны, они меньше набираются (нет необходимости повторять имя переменной), упрощают обслуживание при изменении / удалении переменной ... легче найти отсутствующий комментарий. Сочетал бы это с правильной строкой документа под подписью. +1
Марк Хорват
Это не работает как документация. Если вы прокомментируете свой пакет таким образом, и пользователь PyCharm загружает его, он не сможет проверить, что делает каждый параметр, не имея доступа к вашей документации - которую вы не сможете сгенерировать с помощью какого-либо программного обеспечения. Если вы не делаете свой собственный. Вот почему OP просит указать это в строке документации. Извините так поздно.
Это просто ужасно
Майкл Уолтерс