欢迎访问宙启技术站
智能推送

Python中wraps()装饰器的灵活应用方法

发布时间:2024-01-10 00:44:17

在Python中,wraps()是一个常用的装饰器,用于包装函数,并将被包装函数的元数据复制到包装函数中。wraps()装饰器包含在functools模块中,可以通过导入该模块来使用装饰器。

wraps()装饰器的主要作用是保留被包装函数的名称、文档字符串、参数列表等元数据,使得包装函数在被调用时,能够像被包装函数一样正常运行,并且方便调试和测试。

下面给出了wraps()装饰器的灵活应用方法及使用例子:

1. 保留被包装函数的元数据

from functools import wraps

def debug(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling function: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} returned: {result}")
        return result
    return wrapper

@debug
def add(a, b):
    """This function adds two numbers."""
    return a + b

print(add.__name__)  # Output: add
print(add.__doc__)  # Output: This function adds two numbers.

在上面的例子中,debug()装饰器定义了一个wrapper()函数作为包装函数,使用wraps()装饰器将wrapper()函数的元数据设置为被包装函数func的元数据,从而保留了add()函数的名称和文档字符串。

2. 调用被包装函数前后执行其他操作

from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        elapsed_time = time.time() - start_time
        print(f"Function {func.__name_} took {elapsed_time} seconds to run.")
        return result
    return wrapper

@timer
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

fibonacci(10)

在上面的例子中,timer()装饰器定义了一个wrapper()函数作为包装函数,使用wraps()装饰器将wrapper()函数的元数据设置为被包装函数func的元数据。wrapper()函数在调用被包装函数前后,分别记录了开始时间和结束时间,并计算了函数运行所花费的时间。

3. 为被包装函数添加额外参数和选项

from functools import wraps

def logger(output_file):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            with open(output_file, "w") as file:
                file.write(f"Calling function: {func.__name__}
")
                result = func(*args, **kwargs)
                file.write(f"Function {func.__name__} returned: {result}
")
            return result
        return wrapper
    return decorator

@logger("log.txt")
def multiply(a, b):
    return a * b

multiply(2, 3)

在上面的例子中,logger()装饰器定义了一个decorator()函数,接受output_file作为参数,返回一个装饰器函数wrapper()wrapper()函数在调用被包装函数前后,将函数调用信息写入到指定的文件中。

通过上述的例子,我们可以看到wraps()装饰器在保留被包装函数的元数据的同时,还可以方便地执行其他操作,为被包装函数添加额外的参数和选项,从而实现更加灵活的装饰器应用。