声明:参考B站视频,自学成长记录
https://www.bilibili.com/video/BV1qC4y1s71m?p=253
1.什么是装饰器
在不修改原函数的源代码和调用方式前提下
通过定义一个函数来为原函数增加新的功能
2.为什么要有装饰器
客户需求:对已上线的功能进行升级优化改进
代码原则:对拓展功能开放;对修改源代码封闭
3.如何使用装饰器
无参装饰器
'''
无参装饰器定义示例
'''
import time
def outter(func): # func表示被装饰的函数对象(就是函数名字)
def inner(*args, **kwargs): # 接收传进来的参数,传给被装饰的原函数
start = time.time()
# 被装饰的原函数
res = func(*args, **kwargs)
end = time.time()
# 新增功能
print('运行时间:{}'.format(round(end - start, 2)))
return res # res <-- 原函数对象
return inner # inner <-- res <-- 原函数对象
'''无参装饰器调用示例'''
# 语法糖
@outter # @outter 等同于 get = outter(get)
def get(data):
time.sleep(1)
return data + 1
print(get(2021))
"""
运行结果:
运行时间:1.01
2022
"""
有参装饰器
'''
有参装饰器定义示例
'''
def data(data_type):
def outter(func):
def inner(*args,**kwargs):
if data_type == 1:
res = func(*args,**kwargs)
print('注册功能')
else:
res = func(*args,**kwargs)
print('登陆功能')
return res
return inner
return outter
'''
有参装饰器调用示例
'''
@data(1)
# 1. data(1) --> outter
# 2. @data(1) --> @outter
# 3. @outter --> func1 = outter(func1)
def func1(x, y):
return 'func1'
print(func1(1, 2))
"""
运行结果:
注册功能
func1
"""
叠加多个装饰器(自下而上加载 / 自上而下运行)
def outter1(func):
def innner1(*args, **kwargs):
print('装饰器1')
res = func(*args, **kwargs)
return res
return innner1
def wrapper2(x):
def outter2(func):
def innner2(*args, **kwargs):
print('装饰器2')
res = func(*args, **kwargs)
return res
return innner2
return outter2
# 加载顺序(自下而上):
@outter1 # @wrapper2(111) --> @outter --> index=outter(index) --> index=innner2
@wrapper2(111) # @outter1 --> index=outter1(index) --> index=outter1(inner2) --> index=inner1
def index(x, y):
print('index')
# 执行顺序(自上而下):
index(1, 2) # index(1,2) = inner1(1,2) --> inner2(1,2) --> index(1,2)
'''
运行结果:
装饰器1
装饰器2
index
'''