关于python:修改来自装饰器的文档字符串,同时保留格式

Amending docstrings from decoators, while retaining formattting

我有一些decorator函数,它们在执行它们修饰的函数之前/之后执行额外的代码。我想做的是动态地记录修饰函数docstring的附加行为。我已经用functools.wrap保留了这个名字和这样的财产。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
numbers_added = []

def record_number(func):
    decorator_doc = '''
Record 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

现在,这里的一切都很好,docstring已经成功更新,我的问题是什么?如果你看一下help(add2_to_even),你会发现docstring的第二行格式不正确。通常,任何前导压痕都会被剥离,但在这种情况下都会被保留。我该怎么做才能保持预期的格式?

注意:在python-docstring约定(pep 257)中,有一个算法的实现可以实现这一点,但我不想使用类似这样的方法并重新实现核心功能。


inspect.cleandoc函数实质上实现了pep 257中的trim算法。你可以用它来修剪。

由于新的docstring没有缩进,为了将其与旧的docstring结合起来,需要去掉旧的docstring中的缩进。所以您可能需要做的是修剪现有的docstring,然后附加新的docstring。也就是说,将record_number的下一行改为:

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

当我用您的示例尝试时,这会得到正确的结果,尽管我不确定是否会出现边缘情况,在这种情况下,它会为格式更复杂的docstring提供奇怪的输出。