前言:什么是装饰器?Python中装饰器有什么作用?
答:
1、python装饰器是用于拓展原来函数功能的一种函数,目的是在不改变原函数的情况下,给函数增加功能。
2、装饰器是通过闭包实现,所以讲装饰器首先得知道什么是闭包。
一、什么是闭包?
答:
1、一个定义在函数内部的函数,闭包可以让变量脱离了该函数的作用域也依然能被访问到
2、定义一个嵌套函数,内函数内部使用外函数变量,让外函数将内函数当做参数返回,这样就组成了一个闭包
#例子:
def sum_number(age):
def push_name():
E = age*10
return E
return push_name
e = sum_number(3)
a = e()
print(a)
#执行过程分析:
# 1. 调用外函数(sum_number),将参数赋值给age,此时x=3
# 2. 执行外函数(sum_number),内函数(push_name)不会被执行
# 3. 执行到return语句此时返回内函数push_name对象(不会被调用),因为这里只是返回的push_name对象而已
# 4. 此时外函数(sum_number)执行结束的时候发现内部函数会用到自己的临时变量(age)
# 5. 此时外函数(sum_number)临时变量就不会释放,会绑定给内函数内函数(push_name)继续使用
# 6. 此时e得到的结果就是push_name对象
# 7. 此时a = e()就是 a ==内部函数push_name的返回值了
二、什么是解包?
def add(**kwargs): #**kwargs不定长,参数需为字典格式
print(kwargs)#打印kwargs的内容
#方法1:
test_list={"name":"老张","age":"20"}#字典格式的数据
add(**test_list) # 解包成—》add(name="老张",age=20)
#方法2:
add(name="老张",age=20)#不拆包,直接按规定写
三、什么嵌套函数?
答:函数中嵌套函数,使用函数内部函数的返回值
#嵌套函数:
def func():
print("外层函数被调动")
def inner():
print("内层函数被调用")
return inner
a = func()
a()
#执行过程分析:
我们调用函数func,func函数内部又会调用inner函数。那么我们会不会又需求让函数外部调用inner函数呢?既然函数名是变量,我们想要调用内层函数,就以使用返回值的方式将函数返回,来达到这个结果。
四、单层装饰器
答:1、闭包的特性 2、函数可以被当做参数传递
a)语法糖:@函数名,装饰器是一个装饰函数的函数,能够在不改变函数源码和函数调用方式的情况下给函数增加的功能
b)装饰器就是从内到外修饰————就是先从函数头上的装饰器,再执行函数内部
import time
def get_time(f):#函数参数f
def inner(*arg,**kwarg): #函数参数,不定长
s_time = time.time() #获取当前时间(如2022.03.20.14:00)
res = f(*arg,**kwarg) #拆包不定长的内容
e_time = time.time() #获取当前时间(如2022.03.20.14:30)
print("耗时:{}".format(e_time - s_time)) #计算时间差
return res#返回不定长的内容
return inner #返回inner对象
@get_time #糖语法,使用@get_time装饰器
def pay(money):
print("开始支付{}!".format(money))
time.sleep(2)#等待2秒
pay(20) #调用使用了装饰器的函数
————————————————————————————————————————
#响应结果:
开始支付20!
耗时:2.0124311447143555
————————————————————————————————————————
#pay(20)执行过程分析:
1、先执行pay()这个函数体,money = 20
2、开始执行装饰器(@get_time)中的内容
3、先执行外部函数get_time,inner在这里还不会被调用,因为只是返回了inner对象
4、外部函数get_time 发现内部函数inner在使用外部函数的“f”参数
5、内部函数inner 返回在内部的计时数值,然后执行
四、高阶装饰器
问题1:如果多个地方使用了装饰器,但是装饰器需要灵活变通,那如何处理?
#解决:代码:
def tip(content):
def fun1(a):
def fun2():
a()
print(content)
return fun2
return fun1
@tip("这次")
def fun3():
print("微信支付:")
@tip("2.0——虚拟产品支持退款")
def fun4():
print("支付宝支付:")
fun4()
执行解读:
四、多个装饰器
问题2:需要使用多装饰器时,如何处理。问题2:多个装饰器如何执行
答案1:一行一个装饰器 答案2:从上到下。顺序执行
代码:
def tip(content):
def fun1(a):
def fun2():
a()
print(content)
return fun2
return fun1
def anthoer_tip(fun3):
def meme():
print("再来一个装饰器")
return meme
@anthoer_tip
@tip("这次")
def fun3():
print("微信支付:")
@tip("2.0——虚拟产品支持退款")
@anthoer_tip
def fun4():
print("支付宝支付:")
fun4()