装饰器
一. 装饰器定义
##装饰器本质就是一个函数,装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。装饰器本质就是一个函数,装饰器本质上是一 #它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。 #有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
二. 不带参数的装饰器
from functools import wraps import time def wrapper(f): @wraps(f) def inner(*args,**kwargs): #这里参数传递用pack和unpack理解 """在被装饰函数执行之前要做的事""" ret = f(*args,**kwargs) #被装饰的函数 #这里的f就是用的闭包原则,f为被装饰的函数主体 """在被装饰函数执行之后要做的事情""" return ret return inner #装饰器的功能实现,实际上是在inner中,用户执行带装饰器的函数时,实际上就是在执行inner中的内容。 @wrapper #语法糖,这里等作用于 func = wrapper(func) 返回的是inner def func(a,b): time.sleep(0.01) print("hello,world!") return a+b print(func(1,2))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def timer(f): def inner(): start_time = time.time() ret = f() end_time = time.time() print(end_time-start_time) return ret return inner @timer def func(): time.sleep(0.1) print("hello,world!") return "python" print(func())
三. 带参数的装饰器
import time from functools import wraps def timer(flag): #这一层就是为了把参数带进来,可让内层函数调用,这里也用的闭包思想 def decorator(func): @wraps(func) def inner(*args,**kwargs): if flag: start_time = time.time() ret = func(*args, **kwargs) end_time = time.time() print(end_time-start_time) return ret else: return func(*args, **kwargs) return inner return decorator flag = False @timer(flag) #time(flag)这里可以理解为是执行的,返回的是decorator def foo(): time.sleep(0.1) print("hello,world")
四. 总结
#装饰器的实现主要是依赖于函数能作为值传递和闭包实现的,尤其是闭包这块,函数引用闭包,装饰器参数闭包,理解这两个,装饰器就很好理解了。