Wie kann ein ** kwargs-Parameter richtig dokumentiert werden?

99

Ich verwende Sphinx und das Autodoc-Plugin, um API-Dokumentation für meine Python-Module zu generieren. Ich kann zwar sehen, wie bestimmte Parameter gut dokumentiert werden, aber ich kann kein Beispiel dafür finden, wie ein **kwargsParameter dokumentiert wird.

Hat jemand ein gutes Beispiel für eine klare Möglichkeit, diese zu dokumentieren?

jkp
quelle
Dies hängt ganz davon ab, welche Docstring-Methode Sie verwenden. (reStructuredText, Sphinx, Google)
Stevoisiak
2
Dies sollte nicht geschlossen worden sein. Es ist eine gültige Frage. Es ist spezifisch (wie man ** kwargs mit Sphinx dokumentiert) Da Dokumentkommentare in Python nicht vollständig standardisiert sind, führt dies zu Meinungen (oder mehreren Methoden), solange sie die Frage spezifisch unterstützen (Sphinx).
JerodG

Antworten:

5

Ich denke, subprocessdie Dokumente von -module sind ein gutes Beispiel. Geben Sie eine vollständige Liste aller Parameter für eine Top- / Elternklasse an . Beziehen Sie sich dann einfach auf diese Liste für alle anderen Vorkommen von **kwargs.

SilentGhost
quelle
97
Bin ich der einzige, für den diese Antwort keinen Sinn ergab? Ich konnte das fragliche Beispiel nicht finden.
Acumenus
2
Das Beispiel ist wahrscheinlich subprocess.call(*popenargs, **kwargs). Es ist dokumentiert, subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)wo alles nach dem *die erkannten Schlüssel sind **kwargs(oder zumindest die häufig verwendeten)
Nr.
2
Die sinnvollste Fortsetzung davon ist jetzt subprocess.Popenund ich bin mir nicht sicher, ob es kein besonders gutes Beispiel mehr ist.
Donal Fellows
Sofern ich mich nicht irre, ist es in Python 3.7 nicht mehr dokumentiert .
Mateen Ulhaq
10
Downvoting, weil kein aktuelles Beispiel in die Antwort aufgenommen wurde.
naught101
51

Nachdem ich diese Frage gefunden hatte, entschied ich mich für Folgendes: Sphinx ist gültig und funktioniert ziemlich gut:

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

    """

Das r"""..."""ist erforderlich, um dies zu einem "rohen" Dokumentstring zu machen und damit das \*intakt zu halten (damit Sphinx es als wörtliches Wort aufnimmt *und nicht als Beginn der "Betonung").

Die gewählte Formatierung (Liste mit Aufzählungszeichen in Klammern und durch m-Striche getrennte Beschreibung) entspricht einfach der von Sphinx bereitgestellten automatisierten Formatierung.

Sobald Sie sich bemüht haben, den Abschnitt "Schlüsselwortargumente" wie den Standardabschnitt "Parameter" aussehen zu lassen, scheint es möglicherweise einfacher zu sein, Ihren eigenen Parameterabschnitt von Anfang an zu rollen (wie in einigen anderen Antworten angegeben). , aber als Proof of Concept ist dies eine Möglichkeit, einen schönen Look als Ergänzung zu erzielen, **kwargswenn Sie bereits Sphinx verwenden.

Quornian
quelle
26

Von Sphinx analysierte Google Style-Dokumentzeichenfolgen

Haftungsausschluss: nicht getestet.

Aus diesem Ausschnitt des Sphinx-Docstring-Beispiels werden die *argsund **kwargsnicht erweitert :

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.

Ich würde die folgende Lösung für die Kompaktheit vorschlagen :

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

Beachten Sie, wie, Optionalist für **keyArgumente nicht erforderlich .

Andernfalls können Sie versuchen, die * Argumente explizit unter Other Parametersund **kwargsunter Keyword Args(siehe analysierte Abschnitte ) aufzulisten :

    """
    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 
        ...
Oleg
quelle
9

Es gibt ein Doctstring-Beispiel für Sphinx in ihrer Dokumentation. Insbesondere zeigen sie Folgendes:

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

Obwohl du danach gefragt hast ausdrücklich würde ich auch auf den Google Python Style Guide verweisen . Ihr Docstring-Beispiel scheint zu implizieren, dass sie nicht speziell kwargs rufen. (other_silly_variable = Keine)

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 hat eine Frage zur akzeptierten Antwort auf die Dokumentation der Unterprozessverwaltung. Wenn Sie ein Modul importieren, können Sie die Modul-Dokumentzeichenfolgen schnell über inspect.getsource anzeigen.

Ein Beispiel aus dem Python-Interpreter mit der Empfehlung von Silent Ghost:

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

Natürlich können Sie die Moduldokumentation auch über die Hilfefunktion anzeigen. Zum Beispiel Hilfe (Unterprozess)

Ich persönlich bin kein Fan des Subprozess-Docstrings für kwargs als Beispiel, aber wie im Google-Beispiel werden kwargs nicht separat aufgelistet, wie im Sphinx-Dokumentationsbeispiel gezeigt.

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()

Ich füge diese Antwort der Frage von ABB hinzu, da es erwähnenswert ist, dass Sie die Quelle oder Dokumentation eines Moduls auf diese Weise überprüfen können, um Einblicke und Anregungen für das Kommentieren Ihres Codes zu erhalten.

binäres Substrat
quelle
2
Korrektur: Dies ist nicht Teil der Sphinx-Dokumentation, sondern eines unabhängigen "Beispiel-Pypi-Projekts", das sich ausdrücklich als nicht autorisierendes Tutorial beschreibt.
Boycy
other_silly_variableist kein kwargs-Argument, sondern ein ganz normales.
Bugmenot123
4

Wenn jemand nach einer gültigen Syntax sucht. Hier ist ein Beispiel für eine Dokumentzeichenfolge. Genau so habe ich es gemacht, ich hoffe, es ist nützlich für Sie, aber ich kann nicht behaupten, dass es mit etwas Besonderem kompatibel ist.

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
m01
quelle
3
Was ist also mit den einzelnen Keyword-Argumenten?
Maasha
4

Dies hängt vom verwendeten Dokumentationsstil ab. Wenn Sie jedoch den numpydoc- Stil verwenden, wird empfohlen, die Dokumentation zu **kwargsverwenden Other Parameters.

Zum Beispiel nach dem Beispiel von 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}``.
    """

Beachten Sie insbesondere, dass empfohlen wird, die Standardeinstellungen von kwargs anzugeben, da diese aus der Funktionssignatur nicht ersichtlich sind.

Jonas Adler
quelle
1
Ich bin nicht sicher, ob Ihr Vorschlag aus älteren Dokumenten oder aus persönlicher Erfahrung stammt, aber die aktuelle Dokumentation "Andere Parameter" (auf die Sie verweisen) besagt, dass er "zur Beschreibung selten verwendeter Parameter verwendet werden sollte" und "nur verwendet werden soll" Wenn eine Funktion eine große Anzahl von Schlüsselwortparametern hat, um ein Durcheinander im Abschnitt "Parameter" zu vermeiden. "
Ninjakannon
1

Wenn Sie nach einer Möglichkeit suchen, dies im Numpydoc- Stil zu tun , können Sie dies einfach im Abschnitt Parameter ohne Angabe des Typs erwähnen**kwargs - wie im Numpydoc-Beispiel aus dem Handbuch zur napoleanischen Sphinx-Erweiterung und dem Dokumentstring-Handbuch aus dem Pandas-Dokumentationssprint 2018 gezeigt.

Hier ist ein Beispiel , das ich aus gefunden LSST Entwicklerhandbuch , das sehr gut erklärt , was das sein soll Beschreibung der **kwargsParameter:

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

Aufbauend auf dem, was @Jonas Adler vorgeschlagen hat, finde ich es besser, das **kwargsund seine Beschreibung in einen Other ParametersAbschnitt zu setzen - selbst dieses Beispiel aus dem Matplotlib-Dokumentationshandbuch schlägt dasselbe vor.

Jaladh Singhal
quelle