使用装饰器装饰时保留函数文档字符串 类

Preserving function docstrings when decorating them using decorator classes

我想知道编写装饰器的正确方法是什么 class 以便它保留装饰函数的文档字符串。例如,考虑以下代码行:

import functools

class _vectorize:
    """ (private) decorator to vectorize a function """


    def __init__(self, func):
        functools.update_wrapper(self, func)
        self._func = func

    def __call__(self, values, *args, **kwargs):

        return [self._func(val, *args, **kwargs) for val in values]


@_vectorize
def multiply(v, s):
    """ Multiplies all values in `v` by scalar `s`. """
    return v*s

我希望客户端通过调用 help(multiply) 来查看 multiply 函数的文档字符串,但事实并非如此:

>>> help(multiply)

Help on instance of _vectorize in module docstring:

multiply = class _vectorize
 |  (private) decorator to vectorize a function
 |  
 |  Methods defined here:
 |  
 |  __call__(self, values, *args, **kwargs)
 |  
 |  __init__(self, func)

要查看正确的文档,必须直接打印 __doc__ 属性:

>>> print(multiply.__doc__)
 Multiplies all values in `v` by scalar `s`. 

我应该如何修改装饰器以便 help 打印所需的文档?

我使用 functools.wraps,它更短并且适用于您的情况并显示正确的文档字符串:

import functools

def _vectorize(func):
        @functools.wraps(func)
        def wrapFunc(values, *args, **kwargs):
                return [func(val, *args, **kwargs) for val in values]
        return wrapFunc

@_vectorize
def multiply(v, s):
    """ Multiplies all values in `v` by scalar `s`. """
    return v*s

参见:What does functools.wraps do?