文章目录
- 代码解析
- 1. 装饰器定义 timer(func)
- 2. 应用装饰器 @timer
- **执行流程**
- **关键点**
- **实际应用场景**
- **改进版本(带 `functools.wraps`)**
这是一个 Python 装饰器(Decorator) 的示例,用于测量函数的执行时间。下面详细解析它的工作原理和用法:
代码解析
1. 装饰器定义 timer(func)
def timer(func):def wrapper(*args, **kwargs):start = time.time() # 记录开始时间result = func(*args, **kwargs) # 执行被装饰的函数end = time.time() # 记录结束时间print(f"函数 {func.__name__} 执行时间: {end-start:.2f}秒") # 打印耗时return result # 返回原函数的结果return wrapper
timer(func)
是一个装饰器工厂函数,接收一个函数func
作为参数。wrapper(*args, **kwargs)
是实际替换原函数的包装函数:*args
和**kwargs
确保它可以处理任意参数(位置参数和关键字参数)。- 在调用原函数
func(*args, **kwargs)
前后分别记录时间,计算并打印耗时。 - 最后返回原函数的结果
result
,确保装饰器不影响原函数的功能。
2. 应用装饰器 @timer
@timer
def long_running_function():time.sleep(2)
@timer
是语法糖,等价于:long_running_function = timer(long_running_function)
- 调用
long_running_function()
时,实际执行的是wrapper()
函数。
执行流程
- 调用
long_running_function()
。 - 进入
wrapper(*args, **kwargs)
:- 记录
start
时间。 - 执行原函数
func()
(即time.sleep(2)
)。 - 记录
end
时间,计算耗时并打印。 - 返回原函数的结果(此处为
None
,因为time.sleep()
无返回值)。
- 记录
输出示例:
函数 long_running_function 执行时间: 2.00秒
关键点
-
装饰器的作用:
- 在不修改原函数代码的情况下,为其添加新功能(如日志、计时、权限检查等)。
- 符合 开放-封闭原则(对扩展开放,对修改封闭)。
-
*args
和**kwargs
:- 确保装饰器能处理任意参数的函数。例如:
调用@timer def add(a, b):return a + b
add(1, b=2)
时,args
为(1,)
,kwargs
为{'b': 2}
。
- 确保装饰器能处理任意参数的函数。例如:
-
函数属性保留:
- 装饰后函数的
__name__
会变成wrapper
,可通过functools.wraps
修复:from functools import wrapsdef timer(func):@wraps(func)def wrapper(*args, **kwargs):# ...原有逻辑return wrapper
- 装饰后函数的
实际应用场景
- 性能分析:统计函数执行时间。
- 日志记录:记录函数调用参数和结果。
- 权限验证:在函数执行前检查用户权限。
- 缓存:缓存函数结果以避免重复计算(如
@lru_cache
)。
改进版本(带 functools.wraps
)
import time
from functools import wrapsdef timer(func):@wraps(func) # 保留原函数的元信息(如 __name__)def wrapper(*args, **kwargs):start = time.time()result = func(*args, **kwargs)end = time.time()print(f"函数 {func.__name__} 执行时间: {end-start:.2f}秒")return resultreturn wrapper
这样,long_running_function.__name__
仍会返回 "long_running_function"
,而不是 "wrapper"
。