一、前置说明
1、本节目标
- 了解
@functools.wraps
的作用。
2、相关回顾
- Python 装饰器基础
- Python 装饰器执行过程详解
二、主要内容
1、问题代码
下面是一段 不能正确显示函数名
的问题代码:
def log_decorator(func):def wrapper(*args, **kwargs):print(f"Calling {func.__name__} with arguments {args} and keyword arguments {kwargs}")result = func(*args, **kwargs)print(f"{func.__name__} returned: {result}")return resultreturn wrapper@log_decorator
def add(a, b):return a + b@log_decorator
def multiply(x, y):return x * yadd_result = add(2, 3)
print(f"add function name: {add.__name__}") # 输出结果:add function name: wrapperprint(f"===================================")multiply_result = multiply(4, 5)
print(f"multiply function name: {multiply.__name__}") # 输出结果:multiply function name: wrapper
输出结果:
Calling add with arguments (2, 3) and keyword arguments {}
add returned: 5
add function name: wrapper
===================================
Calling multiply with arguments (4, 5) and keyword arguments {}
multiply returned: 20
multiply function name: wrapper
从输出结果中,可以看出,add.__name__
和 multiply.__name__
均没有正确的显示函数名称。
2、正确代码
为了解决这个问题,python 提供了内置的装饰器 @functools.wraps
,它的作用是在自定义装饰器中,复制原始函数的元信息到装饰器返回的新函数中,从而保留原函数的属性,包括:函数名称、文档字符串、参数信息等。
下面是正确使用装饰器的代码:
def log_decorator(func):@functools.wraps(func)def wrapper(*args, **kwargs):print(f"Calling {func.__name__} with arguments {args} and keyword arguments {kwargs}")result = func(*args, **kwargs)print(f"{func.__name__} returned: {result}")return resultreturn wrapper@log_decorator
def add(a, b):return a + b@log_decorator
def multiply(x, y):return x * yadd_result = add(2, 3)
print(f"add function name: {add.__name__}") # 输出结果:add function name: addprint(f"===================================")multiply_result = multiply(4, 5)
print(f"multiply function name: {multiply.__name__}") # 输出结果:multiply function name: multiply
输出结果:
Calling add with arguments (2, 3) and keyword arguments {}
add returned: 5
add function name: add
===================================
Calling multiply with arguments (4, 5) and keyword arguments {}
multiply returned: 20
multiply function name: multiply
三、后置说明
1、要点小结
- 使用 Python 内置的
@functools.wraps
装饰器 ,可以复制原始函数的元信息到装饰器返回的新函数中,保留原函数的属性。 - 正确使用自定义装饰器,需要使用
@functools.wraps
装饰在返回的新函数上。
2、下节准备
- Python 使用类实现装饰器
点击进入《Python装饰器从入门到进阶》总目录