Каков правильный способ документировать параметр ** kwargs?

Я использую sphinx и плагин autodoc для создания документации API для моих модулей Python. Пока я вижу, как хорошо документировать определенные параметры, я не могу найти пример того, как документировать параметр **kwargs.

Есть ли у кого-нибудь хороший пример четкого способа документировать эти данные?

Ответ 1

Я думаю, что документы subprocess -module - хороший пример. Дайте исчерпывающий список всех параметров для верхнего/родительского класса. Тогда просто обратитесь к этому списку для всех других случаев **kwargs.

Ответ 2

После нахождения этого вопроса я остановился на следующем, что является действительным Sphinx и работает достаточно хорошо:

def some_function(first, second="two", **kwargs):
    r"""Fetches and returns this thing

    :param first:
        The first parameter
    :type first: ``int``
    :param second:
        The second parameter
    :type second: ``str``
    :param \**kwargs:
        See below

    :Keyword Arguments:
        * *extra* (``list``) --
          Extra stuff
        * *supplement* (``dict``) --
          Additional content

    """

r"""...""" требуется сделать это "сырой" docstring и, таким образом, сохранить \* неповрежденным (для Sphinx забрать как литерал *, а не начало "акцента" ).

Выбранное форматирование (маркированный список с типом в скобках и описание с разделителем m-dash) просто соответствует автоматическому форматированию, предоставленному Sphinx.

Как только вы перешли к этой попытке сделать раздел "Аргументы ключевых слов" похожим на раздел "Параметры" по умолчанию, похоже, что с самого начала было бы проще свернуть собственный раздел параметров (в соответствии с некоторыми из другие ответы), но в качестве доказательства концепции это один из способов добиться приятного просмотра дополнительного **kwargs, если вы уже используете Sphinx.

Ответ 3

Строки документов Google Style, проанализированные Sphinx

Отказ от ответственности: не проверено.

Из этого выреза в примере со строкой сфинкса *args и **kwargs остались нерасширенными:

def module_level_function(param1, param2=None, *args, **kwargs):
    """
    ...

    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *args: Variable length argument list.
        **kwargs: Arbitrary keyword arguments.

Я бы предложил следующее решение для компактности:

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.
        *param3 (int): description
        *param4 (str): 
        ...
        **key1 (int): description 
        **key2 (int): description 
        ...

Обратите внимание, как, Optional не требуется для **key аргументов.

В противном случае вы можете попытаться явно перечислить аргументы * в разделе " Other Parameters и **kwargs разделе " Keyword Args (см. Разобранные разделы):

    """
    Args:
        param1 (int): The first parameter.
        param2 (Optional[str]): The second parameter. Defaults to None.
            Second line of description should be indented.

    Other Parameters:
        param3 (int): description
        param4 (str): 
        ...

    Keyword Args:
        key1 (int): description 
        key2 (int): description 
        ...

Ответ 4

В документации к Sphinx есть пример аргумента для Sphinx. В частности, они показывают следующее:

def public_fn_with_googley_docstring(name, state=None):
"""This function does something.

Args:
   name (str):  The name to use.

Kwargs:
   state (bool): Current state to be in.

Returns:
   int.  The return code::

      0 -- Success!
      1 -- No good.
      2 -- Try again.

Raises:
   AttributeError, KeyError

A really great idea.  A way you might use me is

>>> print public_fn_with_googley_docstring(name='foo', state=None)
0

BTW, this always returns 0.  **NEVER** use with :class:`MyPublicClass`.

"""
return 0

Хотя вы спрашивали о явно, Я также хотел бы указать Руководство по стилю Google Python. Пример их докштрин, по-видимому, подразумевает, что они не вызывают особых проблем. (other_silly_variable = None)

def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
"""Fetches rows from a Bigtable.

Retrieves rows pertaining to the given keys from the Table instance
represented by big_table.  Silly things may happen if
other_silly_variable is not None.

Args:
    big_table: An open Bigtable Table instance.
    keys: A sequence of strings representing the key of each table row
        to fetch.
    other_silly_variable: Another optional variable, that has a much
        longer name than the other args, and which does nothing.

Returns:
    A dict mapping keys to the corresponding table row data
    fetched. Each row is represented as a tuple of strings. For
    example:

    {'Serak': ('Rigel VII', 'Preparer'),
     'Zim': ('Irk', 'Invader'),
     'Lrrr': ('Omicron Persei 8', 'Emperor')}

    If a key from the keys argument is missing from the dictionary,
    then that row was not found in the table.

Raises:
    IOError: An error occurred accessing the bigtable.Table object.
"""
pass

A-B-B имеет вопрос о принятом ответе на ссылку на документацию по управлению подпроцессом. Если вы импортируете модуль, вы можете быстро увидеть docstrings модуля через inspect.getsource.

Пример из интерпретатора python с использованием рекомендации Silent Ghost:

>>> import subprocess
>>> import inspect
>>> import print inspect.getsource(subprocess)

Конечно, вы также можете просмотреть документацию модуля через функцию справки. Например, help (подпроцесс)

Я не являюсь лично поклонником подпроцесса docstring для kwargs в качестве примера, но, как пример Google, он не перечисляет kwargs отдельно, как показано в примере документации Sphinx.

def call(*popenargs, **kwargs):
"""Run command with arguments.  Wait for command to complete, then
return the returncode attribute.

The arguments are the same as for the Popen constructor.  Example:

retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()

Я включаю этот ответ в вопрос A-B-B, потому что стоит отметить, что вы можете просмотреть источник или документа модуля таким образом, чтобы понять и вдохнуть для комментирования вашего кода.

Ответ 5

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

def bar(x=True, y=False):
    """
    Just some silly bar function.

    :Parameters:
      - `x` (`bool`) - dummy description for x
      - `y` (`string`) - dummy description for y
    :return: (`string`) concatenation of x and y.
    """
    return str(x) + y

def foo (a, b, **kwargs):
    """
    Do foo on a, b and some other objects.

    :Parameters:
      - `a` (`int`) - A number.
      - `b` (`int`, `string`) - Another number, or maybe a string.
      - `\**kwargs` - remaining keyword arguments are passed to `bar`

    :return: Success
    :rtype: `bool`
    """
    return len(str(a) + str(b) + bar(**kwargs)) > 20

Ответ 6

Это зависит от стиля используемой вами документации, но если вы используете стиль numpydoc, рекомендуется документировать **kwargs используя Other Parameters.

Например, следующий пример quornian:

def some_function(first, second="two", **kwargs):
    """Fetches and returns this thing

    Parameters
    ----------
    first : 'int'
        The first parameter
    second : 'str', optional
        The second parameter

    Other Parameters
    ----------------
    extra : 'list', optional
        Extra stuff. Default ''[]''.
    suplement : 'dict', optional
        Additional content. Default ''{'key' : 42}''.
    """

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