Comment documenter une méthode avec des paramètres?

139

Comment documenter des méthodes avec des paramètres en utilisant les chaînes de documentation de Python?

EDIT: PEP 257 donne cet exemple:

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

Est-ce la convention utilisée par la plupart des développeurs Python?

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

Je m'attendais à quelque chose d'un peu plus formel comme

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

Environnement : Python 2.7.1

David Andreoletti
la source
1
Avez-vous lu PEP 257? python.org/dev/peps/pep-0257
NPE
1
Il existe plusieurs `` standards '' mais sur une approche pratique et surtout si vous aimez quelque chose de formel, je recommanderais sphinx . Son intégration dans Pycharm permet de générer des docstrings bien structurés plutôt indolores. IMHO
jojo

Réponses:

86

Sur la base de mon expérience, les conventions numpy de docstring (PEP257) sont les surensemble plus largement répandues suivi des conventions qui sont également soutenues par des outils tels que Sphinx .

Un exemple:

Parameters
----------
x : type
    Description of parameter `x`.
Vladimir Keleshev
la source
2
C'est plus proche de ce à quoi je m'attendais. Malheureusement, j'ai choisi le PEP 257 simple et ajouté ma propre convention (au prix de perdre la documentation HTML / PDF générée automatiquement). Cependant, la prochaine fois, je choisirai cette solution. Merci.
David Andreoletti
5
Lorsque je tente de traiter votre docstring suggérée, Sphinx se plaint SEVERE: Unexpected section title- connaissez-vous un moyen de rendre Sphinx plus heureux à ce sujet?
Brandon Rhodes
@BrandonRhodes ce lien parle de l'utilisation de ces conventions avec Sphinx: github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
Vladimir Keleshev
3
En fait, il manque un espace avant Description. J'ai vérifié la documentation numpy, parce que j'ai immédiatement remarqué et pensé "Attendez une seconde, pourquoi est-ce trois espaces? C'est étrange. Qui utiliserait trois espaces?"
Zelphir Kaltstahl
6
C'était peut-être la meilleure réponse au moment où la question a été posée, mais je pense qu'à partir de maintenant (fin 2017), Sphinx est sorti victorieux.
Alex L
120

Puisque les docstrings sont de forme libre, cela dépend vraiment de ce que vous utilisez pour analyser le code afin de générer la documentation de l'API.

Je recommanderais de vous familiariser avec le balisage Sphinx , car il est largement utilisé et devient le standard de facto pour documenter les projets Python, en partie à cause de l'excellent service readthedocs.org . Pour paraphraser un exemple de la documentation Sphinx en tant qu'extrait de code 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
   '''

Ce balisage prend en charge les références croisées entre les documents et plus encore. Notez que la documentation Sphinx utilise (par exemple) :py:attr:alors que vous pouvez simplement l'utiliser :attr:lors de la documentation à partir du code source.

Naturellement, il existe d'autres outils pour documenter les API. Il y a le Doxygen plus classique qui utilise des \param commandes mais celles-ci ne sont pas spécifiquement conçues pour documenter le code Python comme Sphinx.

Notez qu'il y a une question similaire avec une réponse similaire ici ...

anarcat
la source
9
C'est le style utilisé par défaut par la génération automatique des commentaires de PyCharm
Josiah Yoder
Qu'en est-il de la syntaxe des types composites comme les listes de choses?
matanster le
alors c'est un list.
anarcat
33

Conventions:

Outils:


Mise à jour: depuis Python 3.5, vous pouvez utiliser des indices de type qui sont une syntaxe compacte et lisible par machine:

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

    """

Le principal avantage de cette syntaxe est qu'elle est définie par le langage et qu'elle est sans ambiguïté, donc des outils comme PyCharm peuvent facilement en tirer parti.

Jakub Roztocil
la source
12
Bien que cette réponse soit maintenant la plus votée, aucun des PEP ci-dessus ne fournit de convention pour spécifier les types d'arguments d'une méthode.
koriander
11

Les chaînes de documentation python sont de forme libre , vous pouvez les documenter comme vous le souhaitez.

Exemples:

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

Maintenant, il y a quelques conventions, mais python n'en applique aucune. Certains projets ont leurs propres conventions. Certains outils pour travailler avec des docstrings suivent également des conventions spécifiques.

nosklo
la source
3

Le courant dominant, comme d'autres réponses l'ont déjà souligné, va probablement avec la méthode Sphinx afin que vous puissiez utiliser Sphinx pour générer ces documents sophistiqués plus tard.

Cela étant dit, personnellement, j'utilise parfois le style de commentaire en ligne.

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 autre exemple ici, avec quelques petits détails documentés en ligne:

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

Les avantages (comme @ mark-horvath déjà souligné dans un autre commentaire) sont:

  • Plus important encore, les paramètres et leur documentation restent toujours ensemble, ce qui apporte les avantages suivants:
  • Moins de frappe (pas besoin de répéter le nom de la variable)
  • Maintenance plus facile lors du changement / suppression de variable. Il n'y aura jamais de paragraphe de doc de paramètre orphelin après avoir renommé un paramètre.
  • et plus facile de trouver le commentaire manquant.

Maintenant, certains peuvent penser que ce style a l'air "moche". Mais je dirais que «laid» est un mot subjectif. Une manière plus neutre est de dire que ce style n'est pas courant, donc il peut vous sembler moins familier, donc moins confortable. Encore une fois, «confortable» est également un mot subjectif. Mais le fait est que tous les avantages décrits ci-dessus sont objectifs. Vous ne pouvez pas les atteindre si vous suivez la méthode standard.

Espérons qu'un jour dans le futur, il y aura un outil de génération de documents qui pourra également consommer un tel style en ligne. Cela stimulera l'adoption.

PS: Cette réponse est dérivée de ma propre préférence d'utiliser des commentaires en ligne chaque fois que je le juge opportun. J'utilise également le même style en ligne pour documenter un dictionnaire .

RayLuo
la source
1

S'appuyant sur la réponse des indices de type ( https://stackoverflow.com/a/9195565/2418922 ), qui fournit un moyen mieux structuré de documenter les types de paramètres, il existe également une manière structurée de documenter à la fois le type et les descriptions des paramètres:

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

exemple adopté de: https://pypi.org/project/autocommand/

DreamFlasher
la source
1
Est-ce une syntaxe officielle? C'est super utile, mais je ne le trouve pas dans les documents officiels / PEP ...
Ofri Raviv
1
J'aimerais le savoir aussi, s'il y a un PEP pour cela.
DreamFlasher
-1

Les docstrings ne sont utiles que dans les environnements interactifs, par exemple le shell Python. Lorsque vous documentez des objets qui ne seront pas utilisés de manière interactive (par exemple, des objets internes, des rappels de framework), vous pouvez également utiliser des commentaires réguliers. Voici un style que j'utilise pour suspendre les commentaires en retrait des éléments, chacun sur leur propre ligne, afin que vous sachiez que le commentaire s'applique à:

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

Vous ne pouvez pas faire ce genre de chose avec des docstrings.

Lawrence D'Oliveiro
la source
46
Oh, celui-ci a l'air moche.
Misha Akovantsev
1
Moche oui? Idée intéressante ... aussi oui.
David
2
Les commentaires en ligne pour les variables sont très judicieux, moins de frappe (pas besoin de répéter le nom de la variable), une maintenance plus facile lors du changement / suppression de la variable ... plus facile à trouver le commentaire manquant. Le combinerait avec une docstring appropriée sous la signature. +1
Mark Horvath
Cela ne fonctionne pas comme documentation. Si vous commentez votre package de cette manière et qu'un utilisateur de PyCharm le télécharge, il ne pourra pas vérifier ce que fait chaque paramètre sans accéder à votre documentation - que vous ne pourrez générer avec aucun logiciel. À moins que vous ne fabriquiez le vôtre. C'est pourquoi OP demande de le spécifier dans docstring. Désolé si tard.
C'est tout simplement horrible.
Michael Walters