oro*_*ome 6 python variables signature python-sphinx autodoc
在我的代码中,我有
X_DEFAULT = ['a', 'long', 'list', 'of', 'values', 'that', 'is', 'really', 'ugly', 'to', 'see', 'over', 'and', 'over', 'again', 'every', 'time', 'it', 'is', 'referred', 'to', 'in', 'the', 'documentation']
Run Code Online (Sandbox Code Playgroud)
然后
def some_function(..., x=X_DEFAULT, ...):
Run Code Online (Sandbox Code Playgroud)
以便在我的 Sphinx 文档中,使用(例如,使用.. autofunction::
等)我X_DEFAULT
在签名中得到了整个长而笨重的扩展值some_function
:
some_function ( ..., x=['a', 'long', 'list', 'of', 'values', 'that', 'is', 'really', 'ugly', 'to', '看到', 'over', 'and', 'over', 'again', 'every', 'time', 'it', 'is', 'referred', 'to', 'in', 'the' , '文档'], ... )
有没有办法在生成的文档中抑制这种替换,最好有一个链接到定义X_DEFAULT
:
some_function ( ..., x= X_DEFAULT , ... )
我知道我可以手动覆盖我明确列为 Sphinx 文档指令参数的每个函数和方法的签名,但这不是我的目标。我也知道我可以使用autodoc_docstring_signature
和文档字符串的第一行,但这会产生错误的文档字符串,真正用于内省失败的情况(如 C)。我怀疑我可以做的一些事情autodoc-process-signature
可能已经足够(但不完美),尽管我不确定如何进行。
例如,一种方法将“恢复”已在模块级别定义为“公共常量”(由没有前导下划线的全大写名称识别)的所有值的替换,可以在其中找到唯一名称定义它的模块:
def pretty_signature(app, what, name, obj, options, signature, return_annotation):
if what not in ('function', 'method', 'class'):
return
if signature is None:
return
import inspect
mod = inspect.getmodule(obj)
new_sig = signature
# Get all-caps names with no leading underscore
global_names = [name for name in dir(mod) if name.isupper() if name[0] != '_']
# Get only names of variables with distinct values
names_to_replace = [name for name in global_names
if [mod.__dict__[n] for n in global_names].count(mod.__dict__[name]) == 1]
# Substitute name for value in signature, including quotes in a string value
for var_name in names_to_replace:
var_value = mod.__dict__[var_name]
value_string = str(var_value) if type(var_value) is not str else "'{0}'".format(var_value)
new_sig = new_sig.replace(value_string, var_name)
return new_sig, return_annotation
def setup(app):
app.connect('autodoc-process-signature', pretty_signature)
Run Code Online (Sandbox Code Playgroud)
另一种方法是直接从源代码中获取文档字符串:
import inspect
import re
def pretty_signature(app, what, name, obj, options, signature, return_annotation):
"""Prevent substitution of values for names in signatures by preserving source text."""
if what not in ('function', 'method', 'class') or signature is None:
return
new_sig = signature
if inspect.isfunction(obj) or inspect.isclass(obj) or inspect.ismethod(obj):
sig_obj = obj if not inspect.isclass(obj) else obj.__init__
sig_re = '\((self|cls)?,?\s*(.*?)\)\:'
new_sig = ' '.join(re.search(sig_re, inspect.getsource(sig_obj), re.S).group(2).replace('\n', '').split())
new_sig = '(' + new_sig + ')'
return new_sig, return_annotation
Run Code Online (Sandbox Code Playgroud)