Python 装饰器
一、装饰器
就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数。类似于Spring的切面!
二、应用场景
- 收集函数错误日志信息
- 验证函数使用权限
- 计算函数运行时间
- 定制函数的输入和输出(序列化和反序列化)
三、装饰器的特点:
- 不修改已有函数的源代码
- 不修改已有函数的调用方式
- 给已有函数增加额外的功能
四、 装饰器
(1)装饰器来装饰函数
def check(fn):
def inner():
print('请先检查网络')
fn() #调用函数login
return inner #返回的内部函数引用
#1.使用装饰器来装饰函数
def login():
print('开始登陆啦!')
#2.ch是内部函数的引用
ch=check(login)
ch() #3.调用内部函数
(2)语法糖格式: @装饰器名字,通过语法糖的方式也可以完成对已有函数的装饰
import time
#2>语法糖 @函数名
# @check 等同于 ch=check(login)
@check
def register():
print('准备注册了!')
print('@'*50)
# 直接调用
register()
time.sleep(2) #间隔2秒
register()
函数执行时间统计应用:
def outer1(func):
def inner():
start=time.time()
print(f'装饰器开始时间:{start}s')
func() #调用add()函数
end=time.time()
print(f'装饰器结束时间:{end}s')
print(f'函数执行完成耗时:{end-start}秒')
return inner #返回内部函数的引用
@outer1
def add_data():
ll=[]
#1000万数据添加到列表中
for i in range(10000000):
ll.append(i)
#直接调用
add_data()
五、 通用装饰器的使用
可以装饰任意类型的函数
使用装饰器装饰已有函数的时候,内部函数的类型和要装饰的已有函数的类型保持一致
1 、装饰带有不定长的参数,并返回值的函数
def outer2(func):
def inner(*args,**kwargs):
return '带有 ' + func(*args,**kwargs) + ' 装饰器'
return inner
#一个参数
@outer2
def show2_1(a):
return f'【传一个参数:{a}】'
print(show2_1(9999))
#两个参数
@outer2
def show2_2(a,b):
return f'【传两个参数:{a,b}】'
print(show2_2("you","I"))
#多个参数
@outer2
def show2_3(*args,**kwargs):
return f'【fine,\t列表数据:{args}\t键值数据:{kwargs}】'
print(show2_3(100,88,name='mike',age=18))
六、多个装饰器的使用
多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
# 多个装饰器
def outer1(func):
"""对被装饰的函数的返回值"""
def inner(*args,**kwargs):
return '第一个 '+func()+' 装饰器' #注意必须是函数哦!
return inner
def outer2(func):
def inner(*args,**kwargs):
return '第二个 ' + func(*args,**kwargs) + ' 装饰器'
return inner
@outer1
@outer2
def show3():
return 'okay'
# 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
print(show3())
原理剖析:content = outer1(outer2(content))
分布拆解:content = outer2(content),内部装饰器完成,content = outer2.inner
content = outer1(outer2.inner)