def wrapper(fn): # fn是目标函数 def inner(*args, **kwargs): # 聚合 为目标函数传参,无敌传参,接收到的是元组 # 在执行目标函数以前 ret = fn(*args, **kwargs) # 接收到的全部参数,打散传递给正常参数, 调用目标函数,ret是目标函数的返回值 # 在执行目标函数以后 return ret # 把目标函数返回值返回,保证函数正常运行 return inner @wrapper # target_func = wrapper(target_func) # 此时fn就是target_func def target_func(): pass target_func() # 此时执行的是inner()
二、带有参数的装饰器 python
def wrapper_out(flag): # 装饰器自己的参数 def wrapper(fn): # 目标函数 def inner(*args, **kwargs): # 目标函数执行须要的参数 if flag == True: print('看看天气预报,知道明每天气怎么样') ret = fn(*args,**kwargs) # 在执行目标函数以前 print('下雨了,天气预报不太准啊') return ret else: ret = fn(*args,**kwargs) # 在执行目标函数以前 return ret return inner return wrapper #语法糖 @装饰器 @wrapper_out(True) # 先执行wrapper_out(True),返回一个装饰器,再和@拼接 @装饰器 def pashan(): #被wrapper装饰 print('去登山了') pashan()
三、多个装饰器装饰同一个函数 app
def wrapper1(fn): def inner(*args,**kwargs): print(1111) ret = fn(*args, **kwargs) print(2222) return ret return inner def wrapper2(fn): def inner(*args, **kwargs): print(3333) ret = fn(*args, *kwargs) print(4444) return ret return inner # 就近原则 @wrapper1 @wrapper2 def func(): print('今天你在作什么') func() ''' 1111 3333 今天你在作什么 4444 2222 '''
执行顺序:首先@wrapper1装饰起来,而后获取到一个新函数是wrapper1中的inner,而后执行@wrapper2,这个时候,@wrapper2装饰的就是@wrapper1中的inner了,因此执行顺序就像:第二层装饰器前(第一层装饰器前(目标)第一层装饰器后)第二层装饰器后,程序从左到右执行起来 函数