当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python functools.wraps()用法及代码示例


函数工具是用于高阶函数(作用于或返回其他函数的函数)的标准Python模块。wraps()是一个装饰器,应用于装饰器的包装函数。它更新wrapper函数看起来像wrapped通过处理诸如__name____doc__(文档字符串)等。

用法: @functools.wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES)

参数:
wrapped:要由包装函数修饰的函数名称。
assigned:Tuple,用于指定原始函数的哪些属性直接分配给包装函数上的匹配属性。默认情况下设置为WRAPPER_ASSIGNMENTS(分配给包装函数的__module__,__name__,__qualname__,__annotations__和__doc __(文档字符串))
updated:Tuple指定包装器函数的哪些属性用原始函数中的相应属性更新。默认情况下,设置为WRAPPER_UPDATES(这将更新包装函数的__dict__,即实例字典)。


范例1:没有functools.wraps()

def a_decorator(func):
    def wrapper(*args, **kwargs):
        """A wrapper function"""
        # Extend some capabilities of func 
        func() 
    return wrapper 
  
@a_decorator
def first_function():
    """This is docstring for first function"""
    print("first function") 
  
@a_decorator
def second_function(a):
    """This is docstring for second function"""
    print("second function") 
  
print(first_function.__name__) 
print(first_function.__doc__) 
print(second_function.__name__) 
print(second_function.__doc__)
输出:
wrapper
A wrapper function
wrapper
A wrapper function

现在,如果我们写help(first_function)help(second_function)

print("First Function") 
help(first_function) 
  
print("\nSecond Function") 
help(second_function)
输出:
First Function
Help on function wrapper in module __main__:

wrapper(*args, **kwargs)
    A wrapper function


Second Function
Help on function wrapper in module __main__:

wrapper(*args, **kwargs)
    A wrapper function

虽然上面的代码在逻辑上可以正常工作,但是如果您正在编写API或库,并且有人想知道函数的函数以及函数的名称,或者只是键入help(yourFunction),请考虑一下这一点,它将始终显示包装函数的名称和文档字符串。如果您对不同的函数使用了相同的包装器函数,则这将更加令人困惑,因为它将为每个函数显示相同的详细信息。

理想情况下,它应该显示包装函数的名称和文档字符串,而不是包装函数。手动解决方案是分配__name____doc__返回之前在包装函数中添加属性。

def a_decorator(func):
    def wrapper(*args, **kwargs):
        """A wrapper function"""
        # Extend some capabilities of func 
        func() 
    wrapper.__name__ = func.__name__ 
    wrapper.__doc__ = func.__doc__ 
    return wrapper 
  
@a_decorator
def first_function():
    """This is docstring for first function"""
    print("first function") 
  
@a_decorator
def second_function(a):
    """This is docstring for second function"""
    print("second function") 
  
print(first_function.__name__) 
print(first_function.__doc__) 
print(second_function.__name__) 
print(second_function.__doc__)
输出:
first_function
This is docstring for first function
second_function
This is docstring for second function

这解决了问题,但是如果再次键入help(yourFunction),该怎么办,

print("First Function") 
help(first_function) 
  
print("\nSecond Function") 
help(second_function)

对于first_function:help(first_function)

输出:
First Function
Help on function first_function in module __main__:

first_function(*args, **kwargs)
    This is docstring for first function


Second Function
Help on function second_function in module __main__:

second_function(*args, **kwargs)
    This is docstring for second function

如您所见,它仍然存在问题,即函数的签名,它显示了包装函数为每个函数使用的签名(此处为通用签名)。同样,如果要实现许多装饰器,则必须为它们中的每一个编写这些行。
因此,为了节省时间并提高可读性,我们可以使用functools.wraps()作为包装器函数的装饰器。

示例(带有functools.wraps())

from functools import wraps 
  
def a_decorator(func):
    @wraps(func) 
    def wrapper(*args, **kwargs):
        """A wrapper function"""
  
        # Extend some capabilities of func 
        func() 
    return wrapper 
  
@a_decorator
def first_function():
    """This is docstring for first function"""
    print("first function") 
  
@a_decorator
def second_function(a):
    """This is docstring for second function"""
    print("second function") 
  
print(first_function.__name__) 
print(first_function.__doc__) 
print(second_function.__name__) 
print(second_function.__doc__)
输出:
first_function
This is docstring for first function
second_function
This is docstring for second function

现在,如果我们输入help(first_function)--

print("First Function") 
help(first_function) 
  
print("\nSecond Function") 
help(second_function)
输出:
First Function
Help on function first_function in module __main__:

first_function()
    This is docstring for first function


Second Function
Help on function second_function in module __main__:

second_function(a)
    This is docstring for second function


相关用法


注:本文由纯净天空筛选整理自manishkhurana大神的英文原创作品 Python | functools.wraps() function。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。