从装饰器修改文档字符串,同时保留格式

时间:2014-03-28 21:17:02

标签: python documentation decorator python-decorators

我有一些装饰器函数,它们在执行它们装饰的函数之前/之后执行其他代码。我想要做的是动态地将附加行为记录到已修饰函数的文档字符串中。我已经使用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

现在,这里的一切都很有效,文档字符串已成功更新,那么我的问题是什么?如果您查看help(add2_to_even),您会发现文档字符串的第二行格式不正确。通常会剥离任何前导缩进,但在这种情况下会被保留。我该怎么做才能保持预期的格式?

注意:在Python Docstring Conventions(PEP 257)中有一个算法实现,但我宁愿不使用这样的东西并重新实现核心功能。

1 个答案:

答案 0 :(得分:0)

inspect.cleandoc函数基本上实现了PEP 257中的trim算法。您可以使用它来进行修剪。

由于你的新文档字符串没有缩进,为了将它与旧文档组合,你需要摆脱旧文档中的缩进。所以你可能要做的就是修剪现有的docstring,然后添加你的新文档。也就是说,将record_number的倒数第二行更改为:

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

当我尝试使用您的示例时,这会给出正确的结果,但我不确定是否会出现边缘情况,它会为格式更复杂的文档字符串提供奇怪的输出。