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


99

Я використовую сфінкс та плагін autodoc для створення документації API для моїх модулів Python. Хоча я бачу, як добре документувати конкретні параметри, я не можу знайти приклад того, як документувати **kwargsпараметр.

Хтось має хороший приклад чіткого способу їх документувати?


Це повністю залежить від того, який метод документації ви використовуєте. (reStructuredText, Sphinx, Google)
Stevoisiak 07.03.18

2
Це не повинно було закриватися. Це слушне запитання. Це конкретно (як документувати ** кварги за допомогою сфінкса) Оскільки коментарі до документа не повністю стандартизовані в python, це призведе до думок (або декількох методів), якщо вони конкретно підтримують питання (сфінкс).
JerodG

Відповіді:


5

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


97
Я єдиний, кому ця відповідь не мала сенсу? Я не зміг знайти конкретний приклад, про який йде мова.
Проникність

2
Приклад, ймовірно subprocess.call(*popenargs, **kwargs). Це задокументовано як subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)де все після *є розпізнаними ключами **kwargs(або принаймні тими, що часто використовуються)
нос

2
Найзначнішим продовженням цього є зараз, subprocess.Popenі я не впевнений, що це вже є особливо чудовим прикладом.
Donal Fellows

Якщо я не помиляюсь, це більше не задокументовано в Python 3.7 .
Mateen Ulhaq

10
Проголосував проти за не включення фактичного прикладу до відповіді.
naught101

51

Знайшовши це питання, я зупинився на наступному, що є дійсним Сфінкс і працює досить добре:

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"""..."""Потрібно , щоб зробити це «сирий» і , отже , рядок документації зберегти \*недоторканими (для Сфінкса , щоб забрати як буквального , *а не в початку «упор»).

Обране форматування (маркований список із типовими дужками та описом, розділеним m-тире) просто відповідає автоматизованому форматуванню, наданому Sphinx.

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


26

Доктрини 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 
        ...

9

У їхній документації наведено приклад для 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 = Немає)

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

ABB має запитання щодо прийнятої відповіді на посилання на документацію управління підпроцесом. Якщо ви імпортуєте модуль, ви можете швидко побачити рядки документів модуля через inspect.getsource.

Приклад з інтерпретатора python, що використовує рекомендацію Silent Ghost:

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

Звичайно, ви також можете переглянути документацію до модуля за допомогою довідкової функції. Наприклад довідка (підпроцес)

Я особисто не шанувальник підпроцесу документації для 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()

Я включаю цю відповідь на питання АББ, оскільки варто зазначити, що ви можете переглянути джерело будь-якого модуля або документацію таким чином, щоб отримати розуміння та натхнення для коментування вашого коду.


2
Виправлення: це не частина документації Sphinx, а незалежний `` приклад проекту pypi '', який явно описує себе як неавторитетний підручник.
boycy 14.03.18

other_silly_variableце не аргумент Кварґса, а цілком нормальний.
bugmenot123

4

Якщо хтось ще шукає якийсь дійсний синтаксис .. Ось приклад документації. Це саме те, як я це зробив, сподіваюся, це корисно для вас, але я не можу стверджувати, що воно відповідає чимось зокрема.

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

3
То як щодо окремих аргументів ключових слів?
maasha

4

Це залежить від стилю документації ви використовуєте, але якщо ви використовуєте numpydoc стиль його рекомендує документ , **kwargsвикористовуючи Other Parameters.

Наприклад, наступний приклад кверняка:

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, оскільки вони не очевидні з підпису функції.


1
Я не впевнений, чи ваша пропозиція походить із старих документів чи особистого досвіду, але в поточній документації "Інші параметри" (на яку ви посилаєтесь) зазначено, що її слід "використовувати для опису рідко використовуваних параметрів" і "використовувати" якщо функція має велику кількість параметрів ключового слова, щоб запобігти захаращенню розділу "Параметри".
Ніндзяканнон

1

Якщо ви шукаєте, як це зробити в стилі numpydoc , ви можете просто згадати **kwargsв розділі Параметри, не вказуючи тип - як це продемонстровано в прикладі numpydoc із розширення сфінкса napolean та керівництва документацією з документації pandas sprint 2018.

Ось приклад , який я знайшов з LSST керівництва розробника , який дуже добре пояснює те , що повинно бути опис з **kwargsпараметра:

def demoFunction(namedArg, *args, flag=False, **kwargs):
    """Demonstrate documentation for additional keyword and
    positional arguments.

    Parameters
    ----------
    namedArg : `str`
        A named argument that is documented like always.
    *args : `str`
        Additional names.

        Notice how the type is singular since the user is expected to pass individual
        `str` arguments, even though the function itself sees ``args`` as an iterable
        of `str` objects).
    flag : `bool`
        A regular keyword argument.
    **kwargs
        Additional keyword arguments passed to `otherApi`.

        Usually kwargs are used to pass parameters to other functions and
        methods. If that is the case, be sure to mention (and link) the
        API or APIs that receive the keyword arguments.

        If kwargs are being used to generate a `dict`, use the description to
        document the use of the keys and the types of the values.
    """

В якості альтернативи, спираючись на те, що запропонував @Jonas Adler, я вважаю, що краще розмістити **kwargsта його опис у Other Parametersрозділі - навіть цей приклад з посібника з документації matplotlib пропонує те саме.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.