一层装饰器的情况分析
import time
def timmer(func):
def wrapper(*args,**kwargs):
start=time.time()
func(*args,**kwargs)
end=time.time()
print('process run time is %s'%(end-start))
return wrapper
@timmer
def index():
print('from index')
time.sleep(2)
index()
分析timmer装饰器:
- @timmer首先运行timmer,并把index函数当做参数传给timmer(index),
- 返回wrapper函数并赋值给index,此时的index已经不是最开始的index函数了,
- 这时候指向的是wrapper函数,并把wrapper函数的作用域变为全局了。
- 上面都是加载的步骤,index()表示运行wrapper(),于是进入wrapper函数内执行代码
这是一层装饰器的加载和运行步骤
两层装饰器的情况分析
定义两个装饰函数,一个计算函数运行时间,一个是认证功能
import time
def auth(engine='file'):
def outter(func):
def wrapper1(*args,**kwargs):
if engine=='file':
input_name = input('name>>>')
input_passwd = input('password>>>')
if input_passwd == 'abc' and input_name == 'zz':
print('login successful')
res = func(*args, **kwargs)
elif engine == 'mysql':
print('基于mysql的认证')
else:
print('未识别的认证源')
return res
return wrapper1
return outter
def timmer(func):
def wrapper2(*args,**kwargs):
start=time.time()
func(*args,**kwargs)
end=time.time()
print('process run time is %s'%(end-start))
return wrapper2
@auth(engine='file')
@timmer
def index():
print('this is from index')
time.sleep(2)
index()
当一个被装饰的对象同时叠加多个装饰器时
装饰器的加载顺序是:自下而上
装饰器内wrapper函数的执行顺序是:自上而下
所以index函数首先被timmer装饰,
- @timmer wrapper2=timmer(index) index=wrapper2
- @auth(engine='file') outter=auth(engine='file')-->@outter wrapper1=outter(index-->wrapper2)
- 所以最后index()执行时,其实是执行wrapper1函数,而wrapper1里面的func函数指向index,这个index函数指向wrapper2函数
- 所以在auth函数里面等认证功能执行完毕后,会跳到timmer函数里面执行wrapper2函数,
- 在timmer函数里的func指向index函数,该函数是最开始的index函数,也就是被装饰的函数
- 在timmer函数里会执行最开始的index函数,执行完毕返回到wrapper2,等wrapper2函数执行结束,会返回到wrapper1函数
- wrapper1函数执行完毕,程序结束