How to put a variable into Python docstring

 ̄綄美尐妖づ 提交于 2019-12-28 05:06:10

问题


So I'm trying to create a "dynamic" docstring which is something like this:

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

to basically let the docstring for @param animalType show whatever ANIMAL_TYPES has; so that when this variable is updated, the docstring will be updated automatically.

Unfortunately, however, it doesn't seem working... Does anyone know if there is a way of achieving this?


回答1:


Triple-quoted strings are one big string. Nothing is evaluated inside them. The % part is all part of the string. You'd need to have it operating on the actual string.

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

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

I'm not certain this will work properly, though; docstrings are a bit magic. This will not work; the docstring is evaluated at compile time (as the first statement in the function, given it is a string literal—once it's got the % in it it's not just a string literal), string formatting takes place at runtime, so __doc__ will be empty:

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

If you wanted to work this way, you'd need to do func.__doc__ %= {'ANIMAL_TYPES': ANIMAL_TYPES} after the function is defined. Be aware that this would then break on python -OO if you didn't check that __doc__ was defined, as -OO strips docstrings.

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

This is not the standard technique anyway; the standard technique is to reference the appropriate constant: "Takes one of the animal types in ANIMAL_TYPES", or similar.




回答2:


One way to do this would be to use a decorator. I'm not sure how I feel about this; I actually searched for commentary on this method and found this answer, which rightly notes that it could mask a design problem. But your use case seems sound to me at first glance.

In any case, here's a fairly elegant way to achieve the result you're looking for:

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



回答3:


You can also define a docstring using .__doc__

For example:

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

>>> f.__doc__ = "%s string %s" % (x, y)
>>> print(f.__doc__)
1 string docstring



回答4:


You could simply use cross-references in your docstring to refer to the variable.

So:

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

And in the second:

:param choice: can be one of :attr:`MY_CONST`


来源:https://stackoverflow.com/questions/10307696/how-to-put-a-variable-into-python-docstring

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!