装饰器
•
# 基础的装饰器 def wrappper(func): def inner(*args,**kwargs): '''在函数被调用之前添加的代码''' res = func(*args,**kwargs) '''在函数被调用之后添加的代码''' return res return inner
# 完美的装饰器 from functools import wraps def wrapper(func): @wraps(func) def inner(*args,**kwargs): '''在函数被调用之前添加的代码''' res = func(*args,**kwargs) '''在函数被调用之后添加的代码''' return res return inner @wrapper def func(): # inner() pass func() # 执行func()实际上执行的是inner() func._name_ # 查看func函数的名字,但此时func函数的名字是inner的名字,因此需用 @wraps(func)
# 带参数的装饰器 # @wrapper --> @wrapper(argument) # 三层嵌套函数 def outer(形参): def wrapper(func): def inner(*args,**kwargs): '''在函数被调用之前添加的代码''' ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用 '''在函数被调用之后添加的代码''' return ret eturn inner return wrapper @outer(实参) def func(): pass
# 多个装饰器装饰一个函数 俄罗斯套娃的执行顺序 def wrappper1(func): def inner(*args,**kwargs): '''在函数被调用之前添加的代码1''' 1 res = func(*args,**kwargs) 3 '''在函数被调用之后添加的代码''' 6 return res return inner def wrappper2(func): def inner(*args,**kwargs): '''在函数被调用之前添加的代码''' 2 res = func(*args,**kwargs) 4 '''在函数被调用之后添加的代码''' 5 return res return inner @wrapper1 @wrapper2 def func(): print(' ') func()
• 装饰器的作用 —— 不修改函数的调用方式 但想在原来的函数前后添加功能,可以有多个装饰器,但只对一个函数,有一些装饰作用
• 原则: 开放封闭原则 开放 :扩展是开放的 封闭 :对修改是封闭的
• 图解
• 装饰器例子
def wrapper(f): # 这是装饰器函数 f是被装饰的函数名 def inner(*args,**kwargs): '''在被装饰函数之前要做地事''' res = f(*args,**kwargs) # 动态参数*args,**kwargs要原封不动地传给被装饰的函数f,且被装饰函数执行完的返回值要返回给res接收 '''在被装饰函数之后要做地事''' return res return inner
•
# 装饰器的固定模式 def wrapper(func): # 5 而func就是qqxing def inner(*args,**kwargs): res = func(*args,**kwargs) # 1 被装饰函数需要参数和返回值是res(以res接收它的返回值) #被装饰的函数func(*args,**kwargs) return res # 2 再把res返回给“我” return inner @wrapper # 3 等同于 qqxing = wrapper(qqxing),把下面函数的名字作为参数且执行完装饰器函数(wrapper)之后的返回的inner还叫qqxing def qqxing(): # 4 qqxing()函数“使用”了 wrapper 装饰器 print(520) res = qqxing() # 6 而qqxing此刻是inner,因为qqxing = wrapper(qqxing)中执行完wrapper(qqxing)之后返回的qqxing以res接收返回值 print(res)
•
def wrapper(func): def inner(*args,**kwargs): print('在被装饰的函数执行之前做的事') ret = func(*args,**kwargs) print('在被装饰的函数执行之后做的事') return ret return inner # 把inner的内存地址返回回来,让下一行注释的lover接收 @wrapper # 等效于lover = wrapper(lover) def lover(date): print('We have been %s days falling in love'% date ) return 'love story' ret = lover(24) print(ret)
•
def outer(*args,**kwargs): print(args) print(*args) def inner(*args): print('inner:',args) inner(*args) outer(1,2,3,4) # 关于*args,接收就是聚合,调用就是打散