在Sphinx文档中保留包装/装饰的Python函数的默认参数
问题内容:
如何在修饰函数的文档中替换*args
并替换**kwargs
为真实签名?
假设我有以下装饰器和装饰函数:
import functools
def mywrapper(func):
@functools.wraps(func)
def new_func(*args, **kwargs):
print('Wrapping Ho!')
return func(*args, **kwargs)
return new_func
@mywrapper
def myfunc(foo=42, bar=43):
"""Obscure Addition
:param foo: bar!
:param bar: bla bla
:return: foo + bar
"""
return foo + bar
因此,致电print(myfunc(3, 4))
给我们:
Wrapping Ho!
7
到现在为止还挺好。我还希望我的库包含myfunc
Sphinx正确记录的文档。但是,如果我通过以下方式在我的狮身人面像html页面中包含函数:
.. automodule:: mymodule
:members: myfunc
它实际上将显示为:
myfunc( args,* kwargs)
晦涩的加法
- 参数:
- foo :吧!
- 酒吧 :bla bla
- 返回值: foo + bar
如何摆脱myfunc(*args, **kwargs)
标题中的泛型?应该用 myfunc(foo = 42,bar = 43)
代替。如何更改狮身人面像或装饰器mywrapper
,以使默认关键字参数保留在文档中?
编辑 :
如前所述,这个问题曾经被问过,但是答案并没有那么大的帮助。
但是,我有一个主意,想知道这是否可能。Sphinx是否设置一些环境变量来告诉我的模块它实际上是由Sphinx导入的?如果是这样,我可以简单地修补自己的包装器。如果我的模块是由Sphinx导入的,我的包装器将返回原始函数,而不是包装它们。因此,签名被保留。
问题答案:
我想出了一个猴子补丁functools.wraps
。因此,我只是将其添加到了conf.py
项目文档的sphinxsource
文件夹中的脚本中:
# Monkey-patch functools.wraps
import functools
def no_op_wraps(func):
"""Replaces functools.wraps in order to undo wrapping.
Can be used to preserve the decorated function's signature
in the documentation generated by Sphinx.
"""
def wrapper(decorator):
return func
return wrapper
functools.wraps = no_op_wraps
因此,当通过构建html页面时make html
,functools.wraps
此装饰器no_op_wraps
将替换它,该装饰器仅返回原始函数就什么也不做。