15、装饰器 - 知乎目录:一 装饰器介绍1.1 为何要用装饰器1.2 什么是装饰器二 装饰器的实现2.1 无参装饰器的实现2.2 有参装饰器的实现视频链接强烈推荐配套资料: egon新书来袭干货满满 - linhaifeng一 装饰器介绍1.1 为何要用装饰…https://zhuanlan.zhihu.com/p/109078881这个老师搭配了视频,把装饰器的用途、原理讲的很清楚,以下为整理笔记。
装饰器的作用:在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能
1 无参装饰器的实现
1)源函数index()无参数
import time
def index(): # 原函数
time.sleep(3)
print('Welcome to the index page’)
return 200
def timer(func):
def wrapper(): # 引用外部作用域的变量func
start_time=time.time()
res=func()
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper
index=timer(index) #得到index=wrapper,wrapper携带对外作用域的引用:func=原始的index
index() # 执行的是wrapper(),在wrapper的函数体内再执行最原始的index
def timer(func):
def wrapper(): # 引用外部作用域的变量func
......func........
return wrapperindex=timer(index) #得到index=wrapper,func=原始的index
index() # 执行wrapper(),在wrapper的函数体内再执行最原始的index,达到加功能效果
index=timer(index) 与 @timer等价
2)原函数home(name)有参数
在wrapper、func加参数(*args,**kwargs)来传递原函数参数
def timer(func):
def wrapper(*args,**kwargs): #可传递原函数参数
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper
def home(name):
time.sleep(5)
print('Welcome to the home page',name)
home=timer(home)
home('egon')
@deco3
@deco2
@deco1
def index():
pass
# 等价
index=deco3(deco2(deco1(index)))
2 有参装饰器的实现
在函数外面再包一层auth,加入原函数不涉及的参数,同时修改为@auth(参数)
def auth(driver): # 第三层可以添加闭包内的参数不受限制
def timmer(func): # 第二层必须func
def inner(*args,**kwargs): # 第一层原函数参数
func(*args,**kwargs)
...
return inner
return timmer
@auth(driver='file') #index=timmer,同时传入参数driver
def index(name):
pass
index('lion')
3 用装饰器wraps保留原函数所有属性
from functools import wraps # 引入functools模块下的装饰器wraps
def timer(func):
@wraps(func) # 在替代的函数上加
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper