Как поместить переменную в docstring Python
Итак, я пытаюсь создать "динамическую" docstring, которая выглядит примерно так:
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
"""
чтобы в принципе позволить docstring для @param animalType
показать, что ANIMAL_TYPES
имеет; так что, когда эта переменная будет обновлена, docstring будет обновляться автоматически.
К сожалению, однако, похоже, что это не работает... Кто-нибудь знает, есть ли способ достичь этого?
Ответы
Ответ 1
Строки в тройных кавычках - это одна большая строка. Ничто не оценивается внутри них. Часть %
является частью строки. Вам нужно, чтобы он работал с реальной строкой.
def func(animalType):
"""
This is a sample function.
@param animalType: "It takes one of these animal types %(ANIMAL_TYPES)s"
""" % {'ANIMAL_TYPES': ANIMAL_TYPES}
Я не уверен, что это будет работать должным образом; Строки документа немного волшебны. Это не будет работать; строка документа оценивается во время компиляции (как первый оператор в функции, учитывая, что он является строковым литералом - как только он получил в нем %
а не просто строковый литерал), форматирование строки происходит во время выполнения, поэтому __doc__
будет пустым:
>>> def a(): 'docstring works'
...
>>> a.__doc__
'docstring works'
>>> def b(): "formatted docstring doesn't work %s" % ':-('
...
>>> b.__doc__
>>>
Если вы хотите работать таким образом, вам нужно будет выполнить func.__doc__ %= {'ANIMAL_TYPES': ANIMAL_TYPES}
после определения функции. Имейте в python -OO
что это может python -OO
если вы не проверите, что __doc__
был определен, так как -OO
удаляет строки документации.
>>> def c(): "formatted docstring works %s"
...
>>> c.__doc__
"formatted docstring works %s"
>>> c.__doc__ %= 'after'
>>> c.__doc__
"formatted docstring works after"
В любом случае, это не стандартная техника; стандартным методом является ссылка на соответствующую константу: "Принимает один из типов животных в ANIMAL_TYPES" или аналогичный.
Ответ 2
Один из способов сделать это - использовать декоратор. Я не уверен, как я к этому отношусь; Я действительно искал комментарий к этому методу и нашел этот ответ, который по праву отмечает, что он может маскировать проблему дизайна. Но ваш случай использования кажется мне на первый взгляд.
В любом случае, здесь довольно элегантный способ добиться результата, который вы ищете:
>>> 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
Вы также можете определить docstring с помощью .__doc__
Например:
>>> def f():
pass
>>> x = 1
>>> y = "docstring"
>>> f.__doc__ = "%s string %s" % (x, y)
>>> print(f.__doc__)
1 string docstring
Ответ 4
Вы можете просто использовать перекрестные ссылки в вашей строке документации для ссылки на переменную.
Так:
:param animalType: It takes one of these :data:'animal types<ANIMAL_TYPES>'
И во втором:
:param choice: can be one of :attr:'MY_CONST'