一:装饰器
在不改变原函数的基础上,额外的添加功能。
装饰器的返回值是一个函数对象。
装饰器应用:日志,性能测试,事务处理,缓存等场景。
二:装饰器形成过程
一个函数的应用:计算执行时间
import time def func1(): print('in func1') def timer(func): def inner(): start_time=time.time() func() end_time=time.time() print(end_time-start_time) return inner func1=timer(func1) func1()
多个函数的应用时候用func1=timer(func1)太麻烦了,于是有了语法糖。
不带参数装饰器(简单装饰器)
import time def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner @timer #==> func1 = timer(func1) def func1(): print('in func1') func1()
万能装饰器(带参数的函数)
def wrapper(func): def inner(*args,**kwargs): ret=func(*args,**kwargs) return ret return inner # @wrapper # def func(): # print() # func()
解读:省略部分是我们要调用这个装饰器执行函数的时候用到的。
带参数装饰器(查看函数名和声明信息)
def wrapper(func): def inner(*args,**kwargs): ret=func(*args,**kwargs) return ret return inner @wrapper def func(): print() func()
from functools import wraps def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__)
带flag装饰器
def outer(flag): print('不用上班') def wrapper(func): print('在挺一周') def inner(*args,**kwargs): if flag: print('装饰器真头疼') ret=func(*args,**kwargs) if flag: print('我去,还不完') return ret return inner return wrapper @outer(True) def func(): print('终于放假了') func()
bug:@outer(True)必须放500个
改进
flag = True def wrapper_out(flag): def wrapper(func): def inner(*args,**kwargs): '''执行函数前''' if flag: ret = func(*args,**kwargs) '''执行函数后''' print(222) return ret else: ret = func() return ret return inner return wrapper @wrapper_out(flag) #第一步是调用 wrapper_out(flag),接收到返回值wrapper def func(): #第二步是@wrapper,即func = wrapper(func) print(111) func()
多个装饰器装饰一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()
来源:oschina
链接:https://my.oschina.net/u/3657436/blog/1618770