Wie dokumentiere ich eine Methode mit Parametern?

139

Wie dokumentiere ich Methoden mit Parametern mithilfe der Python-Dokumentationszeichenfolgen?

EDIT: PEP 257 gibt dieses Beispiel:

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

Ist dies die Konvention, die von den meisten Python-Entwicklern verwendet wird?

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

Ich hatte etwas Formaleres erwartet wie

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

Umgebung : Python 2.7.1

David Andreoletti
quelle
1
Haben Sie PEP 257 gelesen? python.org/dev/peps/pep-0257
NPE
1
Es gibt verschiedene "Standards", aber in Bezug auf einen praktischen Ansatz und besonders wenn Sie etwas Formales mögen, würde ich Sphinx empfehlen . Die Integration in Pycharm macht das Generieren gut strukturierter Docstrings ziemlich schmerzlos. IMHO
Jojo

Antworten:

85

Aufgrund meiner Erfahrung, die numpy docstring Konventionen (PEP257 Obermenge) sind die am weitesten verbreiteten gefolgt Konventionen, die auch von Werkzeugen, wie unterstützt Sphinx .

Ein Beispiel:

Parameters
----------
x : type
    Description of parameter `x`.
Vladimir Keleshev
quelle
2
Dies ist näher an dem, was ich erwartet hatte. Leider habe ich mich für einfaches PEP 257 entschieden und meine eigene Konvention hinzugefügt (auf Kosten des Verlusts der automatisch generierten HTML / PDF-Dokumentation). Beim nächsten Mal werde ich mich jedoch für diese Lösung entscheiden. Vielen Dank.
David Andreoletti
5
Wenn ich versuche, Ihren vorgeschlagenen Dokumentstring zu verarbeiten, beschwert sich Sphinx SEVERE: Unexpected section title- wissen Sie, wie Sie Sphinx darüber glücklicher machen können?
Brandon Rhodes
@BrandonRhodes dieser Link spricht über die Verwendung dieser Konventionen mit Sphinx: github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Vladimir Keleshev
3
Eigentlich fehlt vorher ein Leerzeichen Description. Ich überprüfte die Numpy-Dokumentation, weil ich sofort bemerkte und dachte: "
Zelphir Kaltstahl
6
Dies war vielleicht die beste Antwort zu dem Zeitpunkt, als die Frage gestellt wurde, aber ich denke, dass Sphinx ab sofort (Ende 2017) als Sieger hervorgegangen ist.
Alex L
120

Da Docstrings Freiform sind, hängt es wirklich davon ab, was Sie zum Parsen von Code zum Generieren von API-Dokumentation verwenden.

Ich würde empfehlen, sich mit dem Sphinx-Markup vertraut zu machen , da es weit verbreitet ist und zum De-facto-Standard für die Dokumentation von Python-Projekten wird, auch aufgrund des hervorragenden Dienstes readthedocs.org . So umschreiben Sie ein Beispiel aus der Sphinx-Dokumentation als Python-Snippet:

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

Dieses Markup unterstützt Querverweise zwischen Dokumenten und mehr. Beachten Sie, dass in der Sphinx-Dokumentation (z. B.) verwendet wird, :py:attr:während Sie diese nur :attr:beim Dokumentieren aus dem Quellcode verwenden können.

Natürlich gibt es auch andere Tools zum Dokumentieren von APIs. Es gibt das klassischere Doxygen , das \param Befehle verwendet , die jedoch nicht speziell für die Dokumentation von Python-Code wie Sphinx entwickelt wurden.

Beachten Sie, dass es hier eine ähnliche Frage mit einer ähnlichen Antwort gibt ...

anarcat
quelle
9
Dies ist der Stil, der standardmäßig von PyCharms Kommentarautogeneration verwendet wird
Josiah Yoder
Was ist mit der Syntax von zusammengesetzten Typen wie Listen von Dingen?
Matanster
dann ist es ein list.
Anarcat
33

Konventionen:

Werkzeuge:


Update: Seit Python 3.5 können Sie Typhinweise verwenden, die eine kompakte, maschinenlesbare Syntax darstellen:

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

    """

Der Hauptvorteil dieser Syntax besteht darin, dass sie durch die Sprache definiert und eindeutig ist, sodass Tools wie PyCharm leicht davon profitieren können.

Jakub Roztocil
quelle
12
Obwohl diese Antwort jetzt die am besten bewertete ist, bietet keine der oben genannten PEPs eine Konvention zur Angabe der Argumenttypen einer Methode.
Koriander
11

Python-Dokumentzeichenfolgen sind Freiform- Zeichenfolgen. Sie können sie nach Belieben dokumentieren.

Beispiele:

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

Nun gibt es einige Konventionen, aber Python erzwingt keine von ihnen. Einige Projekte haben ihre eigenen Konventionen. Einige Tools zum Arbeiten mit Docstrings folgen ebenfalls bestimmten Konventionen.

nosklo
quelle
3

Wie andere Antworten hier bereits dargelegt haben, geht der Mainstream wahrscheinlich mit der Sphinx-Methode einher, sodass Sie Sphinx verwenden können, um diese ausgefallenen Dokumente später zu generieren.

Davon abgesehen gehe ich gelegentlich gelegentlich mit Inline-Kommentaren um.

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

Ein weiteres Beispiel hier mit einigen winzigen Details, die inline dokumentiert sind:

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

Die Vorteile (wie @ mark-horvath bereits in einem anderen Kommentar hervorgehoben hat) sind:

  • Am wichtigsten ist, dass Parameter und ihr Dokument immer zusammen bleiben, was die folgenden Vorteile bringt:
  • Weniger tippen (Variablenname muss nicht wiederholt werden)
  • Einfachere Wartung beim Ändern / Entfernen der Variablen. Nach dem Umbenennen eines Parameters wird es niemals einen verwaisten Parameter-Doc-Absatz geben.
  • und leichter, fehlende Kommentare zu finden.

Nun mögen einige denken, dass dieser Stil "hässlich" aussieht. Aber ich würde sagen, "hässlich" ist ein subjektives Wort. Eine neutralere Art ist zu sagen, dass dieser Stil kein Mainstream ist, so dass er Ihnen weniger vertraut und daher weniger bequem erscheint. Auch hier ist "bequem" ein subjektives Wort. Der Punkt ist jedoch, dass alle oben beschriebenen Vorteile objektiv sind. Sie können sie nicht erreichen, wenn Sie dem Standardweg folgen.

Hoffentlich wird es eines Tages ein Dokumentgenerator-Tool geben, das auch einen solchen Inline-Stil verwenden kann. Das wird die Adoption vorantreiben.

PS: Diese Antwort ergibt sich aus meiner eigenen Präferenz, Inline-Kommentare zu verwenden, wann immer ich es für richtig halte. Ich verwende den gleichen Inline-Stil, um auch ein Wörterbuch zu dokumentieren .

RayLuo
quelle
1

Aufbauend auf der Antwort auf Typhinweise ( https://stackoverflow.com/a/9195565/2418922 ), die eine besser strukturierte Möglichkeit zur Dokumentation von Parametertypen bietet, gibt es auch eine strukturierte Methode zur Dokumentation von Typ und Beschreibung von Parametern:

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

Beispiel übernommen von: https://pypi.org/project/autocommand/

DreamFlasher
quelle
1
Ist das eine offizielle Syntax? Es ist super nützlich, aber ich kann es nicht in den offiziellen Dokumenten / PEPs finden ...
Ofri Raviv
1
Das würde ich auch gerne wissen, wenn es einen PEP dafür gibt.
DreamFlasher
-1

Docstrings sind nur in interaktiven Umgebungen nützlich, z. B. in der Python-Shell. Wenn Sie Objekte dokumentieren, die nicht interaktiv verwendet werden sollen (z. B. interne Objekte, Framework-Rückrufe), können Sie auch regelmäßige Kommentare verwenden. Hier ist ein Stil, den ich zum Aufhängen eingerückter Kommentare an Elementen verwende, die jeweils in einer eigenen Zeile stehen, damit Sie wissen, dass der Kommentar gilt für:

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

Mit docstrings kann man so etwas nicht machen.

Lawrence D'Oliveiro
quelle
46
Oh, dieser sieht hässlich aus.
Mischa Akovantsev
1
Hässlich ja? Interessante Idee ... auch ja.
David
2
Inline-Kommentare für die Variablen sind sehr sinnvoll, weniger Eingabe (keine Notwendigkeit, den Variablennamen zu wiederholen), einfachere Wartung beim Ändern / Entfernen der Variablen ... einfacher, fehlende Kommentare zu finden. Würde es mit der richtigen Dokumentzeichenfolge unterhalb der Signatur kombinieren. +1
Mark Horvath
Das funktioniert nicht als Dokumentation. Wenn Sie Ihr Paket wie folgt kommentieren und ein PyCharm-Benutzer es herunterlädt, kann er nicht überprüfen, was die einzelnen Parameter tun, ohne auf Ihre Dokumentation zuzugreifen - die Sie mit keiner Software generieren können. Es sei denn, Sie machen Ihre eigenen. Aus diesem Grund fordert OP die Angabe in docstring an. Entschuldigung so spät.
Das ist einfach schrecklich.
Michael Walters