装饰器万能模板
装饰器函数的本质:闭包函数
def wrapper(func): #装饰器函数,func为被装饰函数
def inner(*args,**kwargs):
"""被装饰函数前需要添加的内容"""
ret=func(*args,**kwargs) #被装饰函数
"""被装饰函数后需要添加的内容"""
return ret
return inner
*args :按照位置传值,多余的参数都给args,以元祖的形式存储
**kwargs :按照关键字传值,多余的参数个kwargs,以字典的形式存储
使用方法
@wrapper
def fun():
print('你好')
@wrapper 被称为语法糖,@+装饰器函数名称,写在函数上放,装饰距离最近的函数。
此符号等价于fun=wrapper(fun)
再次执行被装饰函数时,实际执行的是装饰器内部函数inner
装饰器优势
可以在不改变原函数的的基础上为函数添加新的功能,满足对拓展是开放的,对修改是封闭的原则。
装饰器进阶
1. 带参数装饰器
如果想使用@wrapper(flag)类似这样带参数的装饰器,需要在装饰器外层再嵌套一层函数,然后return之前的wrapper函数。
def out_wrapper(flag):
def wrapper(func): #装饰器函数,func为被装饰函数
def inner(*args,**kwargs):
"""被装饰函数前需要添加的内容"""
ret=func(*args,**kwargs) #被装饰函数
"""被装饰函数后需要添加的内容"""
return ret
return inner
return wrapper
2. 多个装饰器调用
def wrapper1(func):
def inner(*args,**ksargs):
print('wrapper1')
ret=func()
print('wrapper1')
return ret
return inner
def wrapper2(func):
def inner(*args,**ksargs):
print('wrapper2')
ret=func()
print('wrapper2')
return ret
return inner
def wrapper3(func):
def inner(*args,**ksargs):
print('wrapper3')
ret=func()
print('wrapper3')
return ret
return inner
@wrapper3
@wrapper2
@wrapper1
def fun():
print('func1')
fun()
多个装饰器,运行顺序是从距离被装饰函数最近的一个装饰器开始的,即从wrapper1,wrapper2,wrapper3,一层一层嵌套,但从打印的结果可知,在被装饰函数之前运行的是从外到内的顺序,之后运行的是从内到外的顺序,类似套娃的结构。
打印结果如下:
wrapper3
wrapper2
wrapper1
func1
wrapper1
wrapper2
wrapper3