Comment mettre une variable dans docstring Python

donc j'essaye de créer un docstring" dynamique " qui est quelque chose comme ceci:

ANIMAL_TYPES = ["mammals", "reptiles", "other"]

def func(animalType):
""" This is a sample function.

    @param animalType: "It takes one of these animal types %s" % ANIMAL_TYPES
"""

pour laisser essentiellement le docstring pour @param animalType montrer tout ce que ANIMAL_TYPES has; de sorte que lorsque cette variable est mise à jour, le docstring sera mis à jour automatiquement.

malheureusement, cela ne semble pas fonctionner... Personne ne sait si il existe un moyen d'atteindre cet objectif?

30
demandé sur Mark Amery 2012-04-25 04:07:46

4 réponses

les cordes Triple-citées sont une grosse corde. Rien n'est évalué à l'intérieur. % une partie fait partie de la chaîne. Il faudrait le faire fonctionner sur la ficelle.

def func(animalType):
    """
    This is a sample function.

    @param animalType: "It takes one of these animal types %(ANIMAL_TYPES)s"
    """ % {'ANIMAL_TYPES': ANIMAL_TYPES}

Je ne suis pas certain que cela fonctionne correctement, bien que; docstrings sont un peu magique. Ce sera travail; le docstring est évalué au moment de la compilation (comme première instruction dans la fonction, étant donné qu'il s'agit d'une chaîne littérale-une fois qu'il a le % dans ce ce n'est pas juste une chaîne littérale), le formatage de la chaîne a lieu à l'exécution, donc __doc__ sera vide:

>>> def a(): 'docstring works'
... 
>>> a.__doc__
'docstring works'
>>> def b(): "formatted docstring doesn't work %s" % ':-('
... 
>>> b.__doc__
>>> 

Si vous voulais travailler de cette façon, vous devez faire func.__doc__ %= {'ANIMAL_TYPES': ANIMAL_TYPES} après la définition de la fonction. Soyez conscient que cela pourrait alors casser sur python -OO si vous n'avez pas vérifier que __doc__ a été défini, comme -OO bandes docstrings.

>>> def c(): "formatted docstring works %s"
... 
>>> c.__doc__
"formatted docstring works %s"
>>> c.__doc__ %= 'after'
>>> c.__doc__
"formatted docstring works after"

ce n'est pas la technique standard de toute façon; la technique standard est de faire référence à la constante appropriée: "prend un de les types d'animaux dans ANIMAL_TYPES", ou similaire.

13
répondu Chris Morgan 2012-04-25 00:19:10

Une façon de faire cela est d'utiliser un décorateur. Je ne suis pas sûr de ce que je pense à ce sujet; j'ai effectivement cherché des commentaires sur cette méthode et trouvé cette réponse, qui souligne à juste titre qu'il pourrait masquer un problème de conception. Mais votre cas d'utilisation semble sonnez pour moi à première vue.

dans tous les cas, voici une façon assez élégante d'atteindre le résultat que vous recherchez:

>>> def docstring_parameter(*sub):
...     def dec(obj):
...         obj.__doc__ = obj.__doc__.format(*sub)
...         return obj
...     return dec
... 
>>> @docstring_parameter('Ocean')
... def foo():
...     '''My Docstring Lies Over The {0}'''
...     pass
... 
>>> @docstring_parameter('Sea')
... def bar():
...     '''My Docstring Lies Over The {0}'''
...     pass
... 
>>> @docstring_parameter('Docstring', 'Me')
... def baz():
...     '''Oh Bring Back My {0} To {1}'''
...     pass
... 
>>> foo.__doc__
'My Docstring Lies Over The Ocean'
>>> bar.__doc__
'My Docstring Lies Over The Sea'
>>> foo.__doc__
'My Docstring Lies Over The Ocean'
>>> baz.__doc__
'Oh Bring Back My Docstring To Me'
31
répondu senderle 2017-05-23 12:02:44

vous pouvez aussi définir un docstring en utilisant .__doc__

Par exemple:

>>> def f():
      pass
>>> x = 1
>>> y = "docstring"

>>> f.__doc__ = "%s string %s" % (x, y)
>>> print(f.__doc__)
1 string docstring
7
répondu Ashwini Chaudhary 2016-11-17 10:13:15

Vous pouvez simplement utiliser [renvois][1] dans votre doc-chaîne pour faire référence à la variable.

Donc:

:param animalType: It takes one of these :data:`animal types<ANIMAL_TYPES>`

Et dans le second:

:param choice: can be one of :attr:`MY_CONST`
1
répondu Dwayne 2012-12-14 13:32:57