python-18-装饰器进阶
前言
假如我们写了几百个甚至更多的函数都用同一个装饰器,这时需不要使用装饰器可怎么办?一个一个取消很现实
但是我们可以写全局的参数,让其生效或不生效。本篇将用带参数的装饰器能解决此问题:
一、带参数的装饰器
1、带参数装饰器,利用全局变量,flag = True or False , # True 就走装饰器 if ,否则不走装饰器,例一:
import time flag = True # True 就走装饰器 if ,否则不走装饰器 def timmer(f): def inner(*args, **kwargs): ''' 多判断一个参数:flag,让其运行或不运行装饰函数 ''' if flag: start = time.time() ret = f(*args, **kwargs) end = time.time() print('已等待:', end-start) return ret else: print('没有等待') ret = f(*args, **kwargs) return ret return inner @ timmer def gs(a): time.sleep(1) return '返回值:', a print(gs(flag))
2、装饰器传参数,三层函数的装饰器,其实就在正常的装饰器再套一层,将你要传入的实参数成为装饰器内的变量参数,例二:
import time flag1 = True def timmer_out(fg): def timmer(f): def inner(*args, **kwargs): if fg: start = time.time() ret = f(*args, **kwargs) end = time.time() print('已等待:', end-start) return ret else: print('没有等待') ret = f(*args, **kwargs) return ret return inner return timmer @ timmer_out(flag1) def gs1(a): time.sleep(1) return '返回值:', a print(gs1(flag1))
两种效果是一样的,一个是利用全局变量,直接判断了;
而后面这种就多嵌套一层函数在装饰器,传入参数,再用此参数判断(有点间接性)
二、俄罗斯套娃,调用多个装饰器
1、如下,既是调用多个装饰器:
# 3、调用多个装饰 # 俄罗斯套娃,上面到下面前置执行一次,然后下面到上面的后置执行一此 def wrapper1(func): def inner1(*args, **kwargs): print('是:wrapper1--前'0) res = func(*args, **kwargs) print('是:wrapper1--后') return res return inner1 def wrapper2(func): def inner2(*args, **kwargs): print('是:wrapper2--前') res = func(*args, **kwargs) print('是:wrapper2--后') return res return inner2 @ wrapper1 @ wrapper2 def f(): print('F') return '拉回给你'
2、可以看到 f 函数上面@1、2的装饰器,这里只需要记住俄罗斯套娃一样一层一层进,一层一层出。
运行结果如下:
3、得出顺序:f 函数 @1、2 的装饰器,顺序为:
① 1 的 被装饰函数前先执行;
② 2 的 被装饰函数前先执行;
③ F 的 执行被装饰函数,不包含返回值;
④ 2 的 被装饰后的代码执行;
⑤ 1 的 被装饰后的代码执行;
⑥ “拉回给你”,被装饰函数的返回值;
4、总结:你会发现就是那么简单,顺序:1→2→被装饰函数,不包含返回值→2→1→被装饰函数返回值。
@的装饰器距离最远被装饰函数那么将先执行,简单的例子:有3个函数,装饰的顺序为:1、2、3;那么在执行时的顺序为:1、2、3、3、2、1
是不是很像套娃呢?欢迎来QQ交流群一起学习:482713805