python中,所谓的装饰器其实是一个函数,这个函数的返回值也是一个函数对象。在装饰器内部,原有函数加装新功能成为新函数后返回给原有的引用
装饰器的作用主要是让其他现有函数在不用修改代码的情况下,新增一些功能。这样就可以将一些函数中的通用代码抽取出来进行复用。
##无参数装饰器
# 这是装饰器函数,参数 func 是被装饰的函数
def decorator(function):
def wrapper(*args, **kw):
# 加装新功能
print('新功能先执行。。。。')
print('新功能先执行完成。。。。')
print('---------------------------------------')
# 执行原来的方法
function(*args, **kw)
# 返回包装好的新函数
return wrapper
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
func=decorator(func)
#这里相当于"func"已经被替换成"wrapper"
func()
执行结果:
新功能先执行。。。。
新功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0
注解形式调用装饰器
之前的装饰器需要手动显示进行调用,可以采用注解方式(也称为语法糖),自动为函数添加装饰器
# 这是装饰器函数,参数 func 是被装饰的函数
def decorator(function):
def wrapper(*args, **kw):
# 加装新功能
print('新功能先执行。。。。')
print('新功能先执行完成。。。。')
print('---------------------------------------')
# 执行原来的方法
function(*args, **kw)
# 返回包装好的新函数
return wrapper
#添加装饰器注解
@decorator
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
#这里无需再进行装饰器调用
func()
执行结果:
新功能先执行。。。。
新功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0
有参装饰器
有些业务场景需要为装饰器传参数,需要在原有的装饰器基础上再包一层,用于接收装饰器所需要的参数
# 装饰器函数,参数 choice 选择添加的新功能
def choose(choice):
def decorator(function):
def wrapper(*args, **kw):
# 加装多个可选新功能
if choice=="in":
print('in功能先执行。。。。')
print('in功能先执行完成。。。。')
elif choice=="out":
print('out功能先执行。。。。')
print('out功能先执行完成。。。。')
print('---------------------------------------')
# 执行原来的方法
function(*args, **kw)
# 返回包装好的新函数
return wrapper
return decorator
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
func=choose(choice="in")(func)
func()
执行结果:
in功能先执行。。。。
in功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0
有参装饰器 语法糖方式
# 装饰器函数,参数 choice 选择添加的新功能
def choose(choice):
def decorator(function):
def wrapper(*args, **kw):
# 加装多个可选新功能
if choice=="in":
print('in功能先执行。。。。')
print('in功能先执行完成。。。。')
elif choice=="out":
print('out功能先执行。。。。')
print('out功能先执行完成。。。。')
print('---------------------------------------')
# 执行原来的方法
function(*args, **kw)
# 返回包装好的新函数
return wrapper
return decorator
@choose(choice="in")
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
func()
执行结果:
in功能先执行。。。。
in功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0
基于类实现的装饰器
基于类实现装饰器时,在init方法中传入被装饰的函数,在call函数中实现装饰器逻辑
class decorator(object):
def __init__(self,func):
self.func=func
def __call__(self, *args, **kwargs):
# 加装新功能
print('新功能先执行。。。。')
print('新功能先执行完成。。。。')
print('---------------------------------------')
return self.func(*args, **kwargs)
@decorator
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
func()
执行结果:
新功能先执行。。。。
新功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0
基于类实现带参数的装饰器
基于类实现的装饰器需要传参时,由init接收参数,call方法接收被装饰的函数,在call内多封装一层函数实现装饰器逻辑
class decorator(object):
def __init__(self,choice):
self.choice=choice
def __call__(self,func):
def wrapper(*args, **kwargs):
# 加装多个可选新功能
if self.choice == "in":
print('in功能先执行。。。。')
print('in功能先执行完成。。。。')
elif self.choice == "out":
print('out功能先执行。。。。')
print('out功能先执行完成。。。。')
print('---------------------------------------')
func(*args, **kwargs)
return wrapper
@decorator(choice="in")
def func():
print("原有功能开始执行。。。")
print("原有功能执行完成。。。")
if __name__=="__main__":
func()
执行结果:
in功能先执行。。。。
in功能先执行完成。。。。
---------------------------------------
原有功能开始执行。。。
原有功能执行完成。。。
Process finished with exit code 0