Come documentare un metodo con i parametri?


139

Come documentare metodi con parametri usando le stringhe di documentazione di Python?

EDIT: PEP 257 fornisce questo esempio:

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

È questa la convenzione utilizzata dalla maggior parte degli sviluppatori Python?

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

Mi aspettavo qualcosa di un po 'più formale come

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

Ambiente : Python 2.7.1


1
Hai letto PEP 257? python.org/dev/peps/pep-0257
NPE

1
Esistono diversi "standard" là fuori ma su un approccio pratico e soprattutto se ti piace qualcosa di formale, consiglierei la sfinge . La sua integrazione in Pycharm rende piuttosto indolore la generazione di dotstring ben strutturati. IMHO
jojo,

Risposte:


86

Sulla base della mia esperienza, le convenzioni intorpidite di docstring (superset PEP257) sono le convenzioni seguite più diffuse che sono supportate anche da strumenti come Sphinx .

Un esempio:

Parameters
----------
x : type
    Description of parameter `x`.

2
Questo è più vicino a quello che mi aspettavo. Sfortunatamente, ho scelto PEP 257 e ho aggiunto la mia convenzione (a costo di perdere la documentazione HTML / PDF generata automaticamente). Tuttavia, la prossima volta sceglierò questa soluzione. Grazie.
David Andreoletti l'

5
Quando tento di elaborare la tua proposta di dotstring, Sphinx si lamenta SEVERE: Unexpected section title: conosci un modo per renderlo più felice?
Brandon Rhodes,

@BrandonRhodes questo link parla dell'uso di queste convenzioni con Sphinx: github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Vladimir Keleshev

3
In realtà prima manca uno spazio Description. Ho controllato la documentazione insensibile, perché ho immediatamente notato e pensato "Aspetta un secondo, perché sono tre spazi? È strano. Chi userebbe tre spazi?"
Zelphir Kaltstahl,

6
Questa potrebbe essere stata la migliore risposta al momento in cui è stata posta la domanda, ma penso che a partire da adesso (fine 2017), la Sfinge sia emersa vittoriosa.
Alex L

120

Poiché i docstring sono in formato libero, dipende davvero da cosa si usa per analizzare il codice per generare la documentazione API.

Consiglierei di familiarizzare con il markup Sphinx , poiché è ampiamente utilizzato e sta diventando lo standard di fatto per la documentazione di progetti Python, in parte grazie all'eccellente servizio readthedocs.org . Per parafrasare un esempio della documentazione di Sphinx come frammento di 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
   '''

Questo markup supporta riferimenti incrociati tra documenti e altro. Si noti che la documentazione di Sphinx utilizza (ad es.) :py:attr:Mentre è possibile utilizzarla solo :attr:quando si documenta dal codice sorgente.

Naturalmente, ci sono altri strumenti per documentare le API. C'è il più classico Doxygen che utilizza i \param comandi, ma quelli non sono specificamente progettati per documentare il codice Python come lo è Sphinx.

Nota che c'è una domanda simile con una risposta simile qui ...


9
Questo è lo stile usato dall'autogenerazione dei commenti di PyCharm per impostazione predefinita
Josiah Yoder,

Che dire della sintassi di tipi compositi come elenchi di cose?
matanster,

allora è un list.
anarcat,

33

Convegni:

Utensili:


Aggiornamento: da Python 3.5 è possibile utilizzare i suggerimenti di tipo che sono una sintassi compatta e leggibile dalla macchina:

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

    """

Il vantaggio principale di questa sintassi è che è definito dalla lingua e non è ambiguo, quindi strumenti come PyCharm possono facilmente trarne vantaggio.


12
Sebbene questa risposta sia ora la più votata, nessuno dei PEP di cui sopra fornisce una convenzione per specificare i tipi di argomenti di un metodo.
koriander,

11

le stringhe di Python sono in formato libero , puoi documentarlo come preferisci.

Esempi:

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

Ora, ci sono alcune convenzioni, ma Python non applica nessuna di esse. Alcuni progetti hanno le loro convenzioni. Alcuni strumenti per lavorare con i docstring seguono anche convenzioni specifiche.



3

Il mainstream è, come già indicato in altre risposte, probabilmente seguendo la via Sfinge in modo che tu possa usare Sphinx per generare quei documenti fantasiosi in seguito.

Detto questo, vado personalmente con lo stile di commento in linea di tanto in tanto.

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

Un altro esempio qui, con alcuni piccoli dettagli documentati in linea:

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

I vantaggi (come già sottolineato da @ mark-horvath in un altro commento) sono:

  • Ancora più importante, i parametri e il loro documento rimangono sempre insieme, il che porta i seguenti vantaggi:
  • Meno digitazione (non è necessario ripetere il nome della variabile)
  • Manutenzione più semplice quando si cambia / rimuove la variabile. Non ci sarà mai alcun paragrafo del documento dei parametri orfani dopo aver rinominato alcuni parametri.
  • e più facile trovare commenti mancanti.

Ora, alcuni potrebbero pensare che questo stile sembri "brutto". Ma direi "brutto" è una parola soggettiva. Un modo più neutrale è dire che questo stile non è mainstream, quindi potrebbe sembrare meno familiare, quindi meno comodo. Ancora una volta, "comodo" è anche una parola soggettiva. Ma il punto è che tutti i vantaggi sopra descritti sono obiettivi. Non puoi raggiungerli se segui il modo standard.

Spero che un giorno in futuro, ci sarà uno strumento di generazione di documenti che può anche consumare uno stile così in linea. Ciò guiderà l'adozione.

PS: Questa risposta deriva dalla mia preferenza di usare commenti in linea ogni volta che lo ritengo opportuno. Uso lo stesso stile in linea anche per documentare un dizionario .


1

Basandosi sulla risposta ai suggerimenti di tipo ( https://stackoverflow.com/a/9195565/2418922 ), che fornisce un modo meglio strutturato per documentare i tipi di parametri, esiste anche un modo strutturato per documentare sia il tipo che le descrizioni dei parametri:

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

esempio adottato da: https://pypi.org/project/autocommand/


1
È una sintassi ufficiale? È super utile, tuttavia non lo trovo nei documenti / PEP ufficiali ...
Ofri Raviv

1
Mi piacerebbe saperlo anche se esiste un PEP per questo.
DreamFlasher

-1

Le docstring sono utili solo all'interno di ambienti interattivi, ad esempio la shell Python. Quando si documentano oggetti che non verranno utilizzati in modo interattivo (ad esempio oggetti interni, callback di framework), è possibile utilizzare anche commenti regolari. Ecco uno stile che uso per appendere i commenti rientrati sugli elementi, ognuno sulla propria riga, quindi sai che il commento si applica a:

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

Non puoi fare questo genere di cose con le stringhe.


46
Oh, questo sembra brutto.
Misha Akovantsev,

1
Brutto si? Idea interessante ... anche sì.
David,

2
I commenti in linea per le variabili sono molto sensibili, meno digitando (non è necessario ripetere il nome della variabile), manutenzione più semplice quando si cambia / rimuove la variabile ... più facile trovare il commento mancante. Lo combinerei con una corretta documentazione sotto la firma. +1
Mark Horvath,

Questo non funziona come documentazione. Se commentate il vostro pacchetto in questo modo e un utente PyCharm lo scarica, non saranno in grado di controllare cosa fa ogni parametro senza accedere alla documentazione - che non sarete in grado di generare con nessun software. A meno che tu non faccia il tuo. Ecco perché OP chiede di specificarlo in docstring. Scusa così tardi.

Questo è semplicemente orribile.
Michael Walters,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.