为什么动态格式化文档字符串不起作用?在功能定义时有没有可接受的解决方法?
>>> DEFAULT_BAR = "moe's tavern"
>>> def foo(bar=DEFAULT_BAR):
... """
... hello this is the docstring
...
... Args:
... bar (str) the bar argument (default: {})
... """.format(DEFAULT_BAR)
...
>>> foo.__doc__
>>> foo.__doc__ is None
True
Run Code Online (Sandbox Code Playgroud)
我尝试使用old-skool样式的%s格式,但也无法正常工作.
您的字符串需要调用函数,但在创建函数时不会执行函数体.
没有执行正确的文档字符串,它只是从解析的源代码中获取并附加到函数对象,没有为此执行任何代码.Python将docstring存储为代码对象中的第一个常量值:
>>> def f():
... """docstring"""
... pass
...
>>> f.__code__.co_consts
('docstring', None)
Run Code Online (Sandbox Code Playgroud)
在构造新函数时将代码对象传递给函数类型(请参阅PyFunction_New()函数).
请参阅函数定义参考文档:
函数定义不执行函数体; 只有在调用函数时才会执行此操作.[3]
[...]
[3]作为函数体中第一个语句出现的字符串文字被转换为函数的
__doc__属性,因此转换为函数的docstring.
您的定义是有效的; 在函数体的顶部没有独立的字符串文字.您的字符串文字是函数本身的一部分,并且仅在调用函数时执行(并且因为您不存储该结果而丢弃结果).
请注意,__doc__函数对象上的属性是可写的; 您可以在创建函数后始终应用变量:
>>> DEFAULT_BAR = "moe's tavern"
>>> def foo(bar=DEFAULT_BAR):
... """
... hello this is the docstring
...
... Args:
... bar (str) the bar argument (default: {})
... """
...
>>> foo.__doc__ = foo.__doc__.format(DEFAULT_BAR)
>>> print(foo.__doc__)
hello this is the docstring
Args:
bar (str) the bar argument (default: moe's tavern)
Run Code Online (Sandbox Code Playgroud)
你可以做,在的帮助下一个装饰functionobject.__globals__和inspect.getargspec()可能,但随后就在模板中使用名为插槽,您可以将一切视为一个字典,并有文档字符串选择什么插值:
from inspect import getargspec
def docstringtemplate(f):
"""Treat the docstring as a template, with access to globals and defaults"""
spec = getargspec(f)
defaults = {} if not spec.defaults else dict(zip(spec.args[-len(spec.defaults):], spec.defaults))
f.__doc__ = f.__doc__ and f.__doc__.format(**dict(f.__globals__, **defaults))
return f
Run Code Online (Sandbox Code Playgroud)
演示:
>>> @docstringtemplate
... def foo(bar=DEFAULT_BAR):
... """
... hello this is the docstring
...
... Args:
... bar (str) the bar argument (default: {bar!r}, or {DEFAULT_BAR!r})
...
... """
...
>>> print(foo.__doc__)
hello this is the docstring
Args:
bar (str) the bar argument (default: "moe's tavern", or "moe's tavern")
Run Code Online (Sandbox Code Playgroud)
函数关键字参数会覆盖全局变量,就像它们在函数中一样.