叠加装饰器的使用是有顺序的:
1.解释@语法是自下而上的
2.执行装饰器是自上而下的
import time state = {"uname": None} def auth(func): def wapper1(*args,**kwargs): if state['uname']: res = func(*args, **kwargs) return res else: uname =input('输入用户名:') upwd = input('输入密码:') if uname == 'bob' and upwd == '123': print('登陆成功...') state['uname'] = uname res = func(*args,**kwargs) return res return wapper1 def timer(func): def wrapper2(*args,**kwargs): start_time = time.time() res=func(*args,**kwargs) end_time = time.time() print(end_time - start_time) return res return wrapper2 @auth @timer def music(): time.sleep(1) print('进入音乐模式...') return 123 music()
@auth在上,执行结果为--->
输入用户名:bob
输入密码:123
登陆成功...
进入音乐模式...
1.0007665157318115@timer在上,执行结果为--->
输入用户名:bob
输入密码:123
登陆成功...
进入音乐模式...
5.942626476287842说明了:timer统计了登录过程的用时
解析:
因为解释@语法是从下自上的,所以--->
1.先解释@timer
python解释器将@下的函数名(music,这个函数名指向music这个函数体的内存地址)作为参数传给timer--->
得到timer(music)--->进一步得到wapper2这个函数名(指向wapper2这个函数体的内存地址),那么此刻@timer 为wapper2,timer内的func = music
2.在解释@auth
python解释器将@下面的函数名wapper2作为参数传给auth-->得到auth(wapper)--->进而得到wapper1这个函数名(指向wapper1的函数体内存地址),而此刻auth内的func = wapper2
而执行是自上而下的..
def auth(func): print('1') def wapper1(*args,**kwargs): print('from auth external') res = func(*args,**kwargs) print('from auth internal') return res return wapper1 def timer(func): print('2') def wrapper2(*args,**kwargs): print('from timer external') res=func(*args,**kwargs) print('from timer internal') return res return wrapper2 @auth @timer def music(): print('进入音乐模式...') music() #执行结果:---> 2 1 from auth external from timer external 进入音乐模式... from timer internal from auth internal
解析:
2在最前面说明python是先解释timer的,拿到wapper2的地址后,解释auth(此时打印1),然后在执行wapper1这个函数体代码,打印from auth external,执行wapper2(*args,**kwargs)时跳到timer内执行wapper2函数体代码,打印from timer external,然后执行music()这个被装饰对象,打印进入音乐模式,然后等待music函数执行完毕后打印from timer internal,等到这步,auth函数内的wapper2才算执行完毕,打印from auth internal
python之路---装饰器补充(嵌套顺序)
猜你喜欢
转载自blog.csdn.net/ltfdsy/article/details/81328883
今日推荐
周排行