Python——装饰器
1. 装饰器
(1)最简单的装饰器
import time def timmer(f): start = time.time() f() end = time.time() print(end-start) def func(): time.sleep(1) print('老板好') timmer(func)
(2)有返回值的装饰器
import time def timmer(f): #装饰器函数 def inner(): start = time.time() ret = f() #被装饰的函数 end = time.time() print(end-start) return ret return inner @timmer #语法糖:放在被装饰函数的前一行 def func(): time.sleep(1) print('你好我好大家好') return '新年好' # func = timmer(func) 有语法糖,可以不写此句话,同义 ret = func() #inner() print(ret)
(3)带一个参数的装饰器
import time def timmer(f): #装饰器函数 def inner(a): start = time.time() ret = f(a) #被装饰的函数 end = time.time() print(end-start) return ret return inner @timmer #语法糖:放在被装饰的函数前一行 def func(a): time.sleep(1) print('你好我好大家好',a) return '新年好' # func = timmer(func) 有语法糖,可以不写此句话,同义 ret = func(1) #inner() print(ret)
(4)带多个参数的装饰器
import time def timmer(f): #装饰器函数 def inner(*args,**kwargs): start = time.time() ret = f(*args,**kwargs) #被装饰的函数 end = time.time() print(end-start) return ret return inner @timmer #语法糖:放在被装饰的函数前一行 def func(a,c,d,b): time.sleep(1) print('你好我好大家好',a,c,d,b) return '新年好' # func = timmer(func) 有语法糖,可以不写此句话,同义 # ret = func(1,2) #inner() # ret = func(1,b = 2) #inner() ret = func(1,3,4,b = 2) #inner() print(ret)
2. 装饰器的作用:
不修改函数的调用方式,但是还想在原来的函数前后添加功能
timmer就是一个装饰器函数,只是对一个函数有些装饰的作用
3. 开放封闭原则
开放:对扩展是开放的
封闭:对修改时封闭的
4. 装饰器的固定模式
import time def wrapper(func): # 装饰器函数,func = qqxing def inner(*args, **kwargs): #被装饰函数之前要做的 ret = func(*args, **kwargs) # func是被装饰的函数 #被装饰函数之前要做的 return ret return inner @wrapper # qqxing = wrapper(qqxing) def qqxing(): print(123) ret = qqxing() # inner print(ret)
5. 装饰器的进阶
(1)functools.wrap
from functools import wraps def wrapper(func):#(1) @wraps(func) def inner(*args,**kwargs):#(4) print('在被装饰的函数执行之前做的事') ret = func(*args,**kwargs)#(8) holiday(*(3),**{}) #(12)ret接收返回值 print('在被装饰的函数执行之后做的事') return ret#(14) return inner#(5) @wrapper #(6)赋值#holiday = wrapper(holiday) #(2,3) def holiday(day): '''这是一个放假通知''' print('中秋放假%s天'%day)#(10) return '好开心'#(11) print(holiday.__name__) #inner(没有wraps) print(holiday.__name__) #holiday(有wraps之后) print(holiday.__doc__) ret = holiday(3) #(7)inner(3) #(15)ret接收返回值 print(ret)#(16)
运行结果:
(2)带参数的装饰器
import time FLAGE = True def timmer_out(flag): def timmer(func): def inner(*args, **kwargs): if flag: start = time.time() ret = func(*args, **kwargs) end = time.time() print(end - start) else: ret = func(*args, **kwargs) return ret return inner return timmer @timmer_out(FLAGE) #timmer = timmer_out(FLAGE) @timmer def wahaha(): time.sleep(0.2) print('wahahahahahaha') @timmer_out(FLAGE) def erguotou(): time.sleep(0.1) print('erguotoutoutou') wahaha() erguotou()
运行结果:
(3)多个装饰器装饰同一个函数
<1>两层
def wrapper1(func): def inner1():#func-->f print('wrapper1,before func') func() #f print('wrapper1,after func') return inner1 def wrapper2(func):#func-->inner1 def inner2(): print('wrapper2,before func') func() #inner1 print('wrapper2,after func') return inner2 @wrapper2 #f = wrapper2(f) = wrapper2(inner1) == inner2 @wrapper1 #f = wrapper1(f) = inner1 def f(): print('in f') f() #-->inner2()
运行结果:
<2>三层
def wrapper1(func): def inner1(): print('wrapper1,before func') func() print('wrapper1,after func') return inner1 def wrapper2(func): def inner2(): print('wrapper2,before func') func() print('wrapper2,after func') return inner2 def wrapper3(func): def inner3(): print('wrapper3,before func') func() print('wrapper3,after func') return inner3 @wrapper3 @wrapper2 @wrapper1 def f(): print('in f') f()
运行结果:
<3>有返回值的完整的三层
def wrapper1(func): def inner1(): print('wrapper1,before func') ret = func() print('wrapper1,after func') return ret return inner1 def wrapper2(func): def inner2(): print('wrapper2,before func') ret = func() print('wrapper2,after func') return ret return inner2 def wrapper3(func): def inner3(): print('wrapper3,before func') ret = func() print('wrapper3,after func') return ret return inner3 @wrapper3 @wrapper2 @wrapper1 def f(): print('in f') print('哈哈哈') f()
运行结果:
<4>执行顺序:
![](https://img2018.cnblogs.com/blog/1408256/201809/1408256-20180920153731150-1072340355.png)
长得丑就应该多读书。我爱学习,只爱学习,最爱学习!