装饰器(Decorator)在Python中是一个挺常见的概念,但刚开始学的时候可能会有点困惑。用户问装饰器的作用是什么,我需要先回顾一下装饰器的基本概念,然后想想如何用简单明了的语言解释清楚。
首先,装饰器是用来修改或增强函数或方法的行为的。它们允许在不改变原有函数代码的情况下,给函数添加新的功能。比如,常见的应用场景包括日志记录、性能测试、权限校验等。例如,想要计算某个函数的执行时间,可以写一个装饰器,而不是在每个函数里都添加计时代码。
接下来,我需要考虑装饰器的工作原理。装饰器本身是一个函数,它接受一个函数作为参数,并返回一个新的函数。这个新函数通常会包装原函数,在调用原函数前后执行一些额外的代码。比如,前面提到的计时功能,装饰器会在调用函数前记录开始时间,在函数执行后计算耗时并输出。
可能还需要举一个具体的例子来说明。比如,定义一个@timer装饰器,用来测量函数执行时间。当用@timer装饰一个函数时,每次调用该函数都会自动计时。这样用户就能直观地看到装饰器是如何工作的。
然后,要提到装饰器的语法,即使用@符号加上装饰器函数名放在被装饰函数的定义之前。这其实是一种语法糖,让代码更简洁易读。例如:
@timer
def my_function():
函数体
这相当于在定义my_function后,将其传递给timer装饰器,并将返回的新函数赋值给my_function。这样原来的my_function就被增强了。
另外,可能需要解释装饰器的嵌套和多个装饰器的执行顺序。比如,如果多个装饰器叠加在一个函数上,它们的执行顺序是从下往上还是从上往下?例如:
@decorator1
@decorator2
def my_function():
pass
这里实际上是decorator2先应用,然后是decorator1,因为装饰器的执行顺序是从最靠近函数的那个开始,逐层向外。不过有时候用户可能会对这个顺序感到困惑,所以需要澄清。
一、装饰器的作用
功能扩展:在不改变原函数逻辑的情况下,为函数添加新功能(如日志、计时、权限校验)。
代码复用:将通用逻辑(如异常重试、缓存)封装成装饰器,避免重复代码。
代码解耦:分离核心逻辑与辅助功能(如日志和业务代码分离)。
权限控制:统一拦截请求,验证用户权限。
二、装饰器的原理
本质:装饰器是一个高阶函数,接受函数作为参数,返回一个新的函数。
语法糖:@decorator 等价于 func = decorator(func)。
三、示例:实现一个计时装饰器
import time
from functools import wraps # 保留原函数元信息
def timer(func):
@wraps(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
def heavy_task(n):
“”“模拟耗时任务”“”
time.sleep(n)
heavy_task(2)