Python 修改解码器中的文档串,同时保留格式化

Python 修改解码器中的文档串,同时保留格式化,python,documentation,decorator,python-decorators,Python,Documentation,Decorator,Python Decorators,我有一些decorator函数,它们在执行它们所修饰的函数之前/之后执行额外的代码。我想做的是动态地将附加行为记录到修饰函数的docstring中。我已经用functools.wrap保留了名称和此类属性 下面是我想做的一个简化示例: numbers_added = [] def record_number(func): decorator_doc = '''\nRecord added numbers in numbers_added''' def add_and_recor

我有一些decorator函数,它们在执行它们所修饰的函数之前/之后执行额外的代码。我想做的是动态地将附加行为记录到修饰函数的docstring中。我已经用
functools.wrap
保留了名称和此类属性

下面是我想做的一个简化示例:

numbers_added = []

def record_number(func):
    decorator_doc = '''\nRecord added numbers in numbers_added'''
    def add_and_record(n):
        r = func(n)
        if r is not False:
            numbers_added.append(n)
        return r
    add_and_record.__doc__ = func.__doc__ + decorator_doc
    return add_and_record

@record_number
def add2_to_even(n):
    '''Add 2 to an even number, `n`.

       If n is not even, return False'''
    if n % 2 == 0:
        return n + 2
    return False
现在,这里的一切都很好,文档字符串已经成功更新,那么我的问题是什么?如果您查看
帮助(将2添加到偶数)
您将看到docstring的第二行没有正确格式化。通常,任何领先的压痕都会被剥离,但在这种情况下,会被保留。我可以做些什么来保持格式符合预期

注意:Python Docstring约定()中有一个算法的实现,但我不希望使用类似的方法来重新实现核心功能。

该函数基本上实现了PEP 257中的
trim
算法。你可以用它来修剪头发

由于您的新docstring没有缩进,为了将它与旧docstring结合起来,您需要去掉旧docstring中的缩进。因此,您可能需要做的是修剪现有的docstring,然后附加新的docstring。也就是说,将
记录编号的倒数第二行更改为:

add_and_record.__doc__ = inspect.cleandoc(func.__doc__) + decorator_doc

当我尝试使用您的示例时,这给出了正确的结果,尽管我不确定是否会出现边缘情况,即它会为具有更复杂格式的docstring提供奇怪的输出。

我对代码进行了测试,结果与之前相同。然而,出于某种原因,我决定尝试使用两个具有相同初始缩进的docstring,它给出了预期的结果。另外,在没有cleandoc的情况下尝试它,但是使用新的缩进修复程序,它仍然会给出预期的结果。因此,我现在有一些东西正在工作,虽然它仍然不完全理想,如果没有更好的解决方案,我可以接受。@JohnHill:你需要做的是在现有的docstring上添加
cleandoc
。请参阅我编辑的答案。