什么是装饰器 让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。 装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。
装饰器的形成过程 如果我想测试某个函数的执行时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import timedef func1 () : print('in func1' ) def timer (func) : def inner () : start = time.time() func() print(time.time() - start) return inner func1 = timer(func1) func1()
但是如果有多个函数,我都想让你测试他们的执行时间,你每次是不是都得func1 = timer(func1)?这样还是有点麻烦,因为这些函数的函数名可能是不相同,有func1,func2,graph,等等,所以更简单的方法,python给你提供了,那就是语法糖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import timedef timer (func) : def inner () : start = time.time() func() print(time.time() - start) return inner @timer def func1 () : time.sleep(1 ) print('in func1' ) func1()
装饰一个带参数的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import timedef timer (func) : def inner (a) : start = time.time() func(a) print(time.time() - start) return inner @timer def func1 (a) : time.sleep(1 ) print(a) func1('hello world' )
装饰一个带各种参数的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import timedef timer (func) : def inner (*args,**kwargs) : start = time.time() func(args,kwargs) print(time.time() - start) return inner @timer def func1 (*args,**kwargs) : print(args,kwargs) func1('hello world' ,'abc' ,123 ,432 )
查看函数的相关信息,在加上装饰器后就失效了
1 2 3 4 5 6 def index () : '''这是一条注释信息''' print('from index' ) print(index.__doc__) print(index.__name__)
导入wraps装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from functools import wrapsdef deco (func) : @wraps(func) def wrapper (*args,**kwargs) : return func(*args,**kwargs) return wrapper @deco def index () : '''这是一条注释信息''' print('from index' ) print(index.__doc__) print(index.__name__)
开放封闭原则 一句话,软件实体应该是可扩展但是不可修改的。
装饰器完美的遵循了这个开放封闭原则
装饰器的主要功能和固定结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def timer (func) : def inner (*args,**kwargs) : '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner from functools import wrapsdef timer (func) : @wraps(func) def wrapper (*args,**kwargs) return func (*args,**kwargs) return wrapper
带参数的装饰器 加上一个outer函数,可以携带一个flag的值,然后控制装饰器是否生效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def outer (flag) : def timer (func) : def inner (*args,**kwargs) : if flag: print('函数开始执行' ) re = func(*args,**kwargs) if flag: print('函数执行完毕' ) return re return inner return timer @outer(True) def func () : print('test' ) func()
多个装饰器装饰一个函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def wrapper1 (func) : def inner () : print('第一个装饰器,在程序运行之前' ) func() print('第一个装饰器,在程序运行之后' ) return inner def wrapper2 (func) : def inner () : print('第二个装饰器,在程序运行之前' ) func() print('第二个装饰器,在程序运行之后' ) return inner @wrapper1 @wrapper2 def f () : print('Hello' ) f()