1.装饰器的特点:
1.函数A作为参数出现的(函数B就接收函数A作为参数)
2.要有闭包的特点
1 """ 2 装饰器的特点: 3 1.函数A作为参数出现的(函数B就接收函数A作为参数) 4 2.要有闭包的特点 5 """ 6 7 8 # 可以将函数作为参数传进另一个函数里面去 9 def funcA(): 10 print("----->test") 11 12 13 def funcB(f): 14 print(f) 15 f() 16 print("------->func") 17 18 19 funcB(funcA)
1 # 定义一个装饰器 2 def decorate(func): 3 a = 10 4 5 def wrapper(): 6 func() 7 print("--------->刷漆") 8 print("--------->铺地板", a) 9 print("--------->装门") 10 return wrapper 11 12 13 # 使用装饰器 14 @decorate 15 def house(): 16 print("我是毛坯房") 17 18 19 # 调用函数 20 house()
整个装饰器的流程
1.house被装饰函数
2.将被装饰的函数作为参数传递给装饰器decorator
3.执行decorate函数
4.将返回值又赋值给house,所以此时的house已经变成wrapper了
# 定义一个装饰器 def decorate(func): a = 10 print("wrapper外层打印测试") def wrapper(): func() print("--------->刷漆") print("--------->铺地板", a) print("--------->装门") print("wrapper加载完成") return wrapper # 使用装饰器 @decorate def house(): print("我是毛坯房") # 调用函数 house() print(house)
2.装饰器加入可变参数和关键字
一个*,会把输入参数组成一个tuple
两个*,会把输入参数打包成字典
1 import time 2 3 4 def decorate(func): 5 def wrapper(*args, **kwargs): # {"clazz":'1904'} 6 print("正在校验中.....") 7 time.sleep(2) 8 print("校验完毕.....") 9 # 调用原函数 10 func(*args, **kwargs) 11 12 return wrapper 13 14 15 @decorate 16 def f1(n): 17 print("----f1-----", n) 18 19 20 @decorate 21 def f2(name, age): 22 print("-----f2-----", name, age) 23 24 25 @decorate 26 def f3(students, clazz='1905'): 27 print("{}班级的学生如下:".format(clazz)) 28 for stu in students: 29 print(stu) 30 31 32 33 f1(5) 34 f2("tom", 20) 35 students = ["ketty", "tony", "rose"] 36 f3(students, clazz='1904')
3.多层装饰器
如果装饰器是多层的,谁距离函数最近,就优先使用那个
1 """ 2 如果装饰器是多层的,谁距离函数最近,就优先使用那个 3 """ 4 5 6 def decorate1(func): 7 print("--------> 1 start") 8 9 def wrapper(*args, **kwargs): 10 func() 11 print("刷漆") 12 print("---------> 1 end") 13 14 return wrapper 15 16 17 def decorate2(func): 18 print("--------> 2 start") 19 20 def wrapper(*args, **kwargs): 21 func() 22 print("铺地板") 23 24 print("------------> 2 end") 25 26 return wrapper 27 28 29 @decorate2 30 @decorate1 31 def house(): 32 print("我是毛坯房") 33 34 35 house()
原理:
def定义一个函数,只是在内存中开辟空间,给出地址,并没有执行
只有调用函数的时候,才去根据地址,进入执行
4.带参数的装饰器
1 """ 2 装饰器带参数,共有三层函数 3 最外层的函数负责接收装饰器参数 4 里面的内容还是原来的装饰器的内容 5 """ 6 7 8 def outer(a): # 第一层:负责接收装饰器的参数 9 def decorate(func): # 第二层:负责接收函数的 10 def wrapper(*args, **kwargs): # 第三层:负责接收函数的参数 11 func(*args) 12 print("------->铺地砖{}块".format(a)) 13 return wrapper # 返出来的是第三层的函数名 14 return decorate # 返出来的是第二层的函数名 15 16 17 @outer(a=10) 18 def house(time): 19 print("我是{}拿到房子钥匙的,还是毛坯房......".format(time)) 20 21 22 @outer(100) 23 def street(): 24 print("新修的街道名字是:春熙路") 25 26 27 house("2019-6-10") 28 street()