做什么函数工具.wrapps是吗?

  • 问题:
  • 在对此的评论中answer to another question,有人说他们不确定函数工具.wrapps正在做。所以,我提出这个问题,以便在StackOverflow上有一个记录供将来参考:什么是函数工具.wrapps是吗?在

  • 答案:
  • 当您使用装饰器时,您是在用另一个函数替换一个函数。换句话说,如果你有一个装修工

    def logged(func):
    def with_logging(*args, **kwargs):
    print(func.__name__ + " was called")
    return func(*args, **kwargs)
    return with_logging

    当你说

    @logged
    def f(x):
    """does some math"""
    return x + x * x

    这和说

    def f(x):
    """does some math"""
    return x + x * x
    f = logged(f)

    你的函数f将被函数替换为带日志的函数。不幸的是,这意味着如果你说

    print(f.__name__)

    它将打印带有日志的,因为这是新函数的名称。事实上,如果您查看f的docstring,它将是空白的,因为带有日志记录的没有docstring,因此您编写的docstring将不再存在。另外,如果您查看该函数的pydoc结果,它不会被列为接受一个参数x;相反,它将被列为接受*args**kwargs,因为这就是日志记录所需要的

    如果使用decorator总是意味着丢失有关函数的信息,那么这将是一个严重的问题。这就是为什么我们有函数工具.wrapps。这接受了decorator中使用的函数,并添加了复制函数名、docstring、arguments list等的功能。由于wrapps本身就是一个decorator,下面的代码执行正确的操作:

    from functools import wraps
    def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
    print(func.__name__ + " was called")
    return func(*args, **kwargs)
    return with_logging

    @logged
    def f(x):
    """does some math"""
    return x + x * x

    print(f.__name__) # prints 'f'
    print(f.__doc__) # prints 'does some math'