使装饰器看起来像装饰功能

装饰器通常会删除功能元数据,因为它们不相同。当使用元编程来动态访问函数元数据时,这可能会导致问题。元数据还包括函数的文档字符串及其名称。 functools.wraps 通过将几个属性复制到包装函数,使装饰函数看起来像原始函数。

from functools import wraps

包装装饰器的两种方法在隐藏原始功能已被装饰时实现了同样的目的。没有理由将函数版本更喜欢类版本,除非你已经使用了另一个版本。

作为一个功能

def decorator(func):
    # Copies the docstring, name, annotations and module to the decorator
    @wraps(func)
    def wrapped_func(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapped_func

@decorator
def test():
    pass

test.__name__

‘测试’

作为一个类

class Decorator(object):
    def __init__(self, func):
        # Copies name, module, annotations and docstring to the instance.
        self._wrapped = wraps(func)(self)
        
    def __call__(self, *args, **kwargs):
        return self._wrapped(*args, **kwargs)

@Decorator
def test():
    """Docstring of test."""
    pass

test.__doc__

‘测试文件。’