装饰器
装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数。让我们从简单的开始,直到能写出实用的装饰器。
1 def outer(some_func): 2 def inner(): 3 print "before some_func" 4 ret = some_func() # 1 5 return ret + 1 6 return inner 7 def foo(): 8 return 1 9 decorated = outer(foo) # 2 10 decorated() 11 12 before some_func 13 2
装饰器的形成过程
1 import time 2 3 def func1(): 4 print('in func1') 5 6 def timer(func): 7 def inner(): 8 start = time.time() 9 func() 10 print(time.time() - start) 11 return inner 12 13 func1 = timer(func1) 14 func1()
装饰器—语法糖
1 import time 2 def timer(func): 3 def inner(): 4 start = time.time() 5 func() 6 print(time.time() - start) 7 return inner 8 9 @timer #==> func1 = timer(func1) 10 def func1(): 11 print('in func1') 12 13 14 func1()
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
装饰器—带参数的装饰器
1 def timer(func): 2 def inner(a): 3 start = time.time() 4 func(a) 5 print(time.time() - start) 6 return inner 7 8 @timer 9 def func1(a): 10 print(a) 11 12 func1(1)
装饰器—成功hold住所有参数的装饰器
1 import time 2 def timer(func): 3 def inner(*args,**kwargs): 4 start = time.time() 5 re = func(*args,**kwargs) 6 print(time.time() - start) 7 return re 8 return inner 9 10 @timer #==> func1 = timer(func1) 11 def func1(a,b): 12 print('in func1') 13 14 @timer #==> func2 = timer(func2) 15 def func2(a): 16 print('in func2 and get a:%s'%(a)) 17 return 'fun2 over' 18 19 func1('aaaaaa','bbbbbb') 20 print(func2('aaaaaa'))
装饰器—带返回值的装饰器
1 import time 2 def timer(func): 3 def inner(*args,**kwargs): 4 start = time.time() 5 re = func(*args,**kwargs) 6 print(time.time() - start) 7 return re 8 return inner 9 10 @timer #==> func1 = timer(func1) 11 def func1(a,b): 12 print('in func1') 13 14 @timer #==> func2 = timer(func2) 15 def func2(a): 16 print('in func2 and get a:%s'%(a)) 17 return 'fun2 over' 18 19 func1('aaaaaa','bbbbbb') 20 print(func2('aaaaaa'))
开放封闭原则
1.对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
装饰器的主要功能和装饰器的固定结构
装饰器的主要功能:
在不改变函数调用方式的基础上在函数的前、后添加功能。
装饰器的固定格式:
1 def timer(func): 2 def inner(*args,**kwargs): 3 '''执行函数之前要做的''' 4 re = func(*args,**kwargs) 5 '''执行函数之后要做的''' 6 return re 7 return inner
带参数的装饰器
1 def outer(flag): 2 def timer(func): 3 def inner(*args,**kwargs): 4 if flag: 5 print('''执行函数之前要做的''') 6 re = func(*args,**kwargs) 7 if flag: 8 print('''执行函数之后要做的''') 9 return re 10 return inner 11 return timer 12 13 @outer(False) 14 def func(): 15 print(111) 16 17 func()
多个装饰器装饰同一个函数
1 def wrapper1(func): 2 def inner(): 3 print('wrapper1 ,before func') 4 func() 5 print('wrapper1 ,after func') 6 return inner 7 8 def wrapper2(func): 9 def inner(): 10 print('wrapper2 ,before func') 11 func() 12 print('wrapper2 ,after func') 13 return inner 14 15 @wrapper2 16 @wrapper1 17 def f(): 18 print('in f') 19 20 f()