装饰器
应用场景:在原有函数的基础上,增加一点功能
例如:下面代码在返回值前面增加字符串‘当前时间:’
1 import time 2 def getXXXTime()
3 return time.strftime('%Y_%m_%d %H:%M:%S',time.localtime())
装饰代码:
1 import time 2 3 # 定义一个装饰器函数 4 def sayLocal(func): 5 def wrapper(): 6 print('当地时间:', end='')
7 return func() 8 return wrapper 9 10 def getXXXTime(): 11 return time.strftime('%Y_%m_%d %H:%M:%S',time.localtime()) 12 13 14 print(getXXXTime()) 15 # 装饰 getXXXTime 16 getXXXTime = sayLocal(getXXXTime) 17 18 print (getXXXTime()) 19 20 # 结果 21 2020_04_14 20:55:49 22 当地时间:2020_04_14 20:55:49
便捷语法:
1 @sayLocal 2 def getXXXTime(): 3 return time.strftime('%Y_%m_%d %H:%M:%S',time.localtime())
被装饰的函数有参数:
例如:
1 import time 2 def getXXXTimeFormat1(name): 3 curTime = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()) 4 return f'{curTime} ,数据采集者:{name} ' 5 6 7 def getXXXTimeFormat2(name,place): 8 curTime = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()) 9 return f'{curTime} ,数据采集者:{name} , 采集地:{place}'
可以使用函数的可变参数:
1 import time 2 3 def sayLocal(func): 4 def wrapper(*args, **kargs): 5 curTime = func(*args, **kargs) 6 return f'当地时间: {curTime}' 7 return wrapper 8 9 @sayLocal 10 def getXXXTimeFormat1(name): 11 curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) 12 return f'{curTime} ,数据采集者:{name} ' 13 14 @sayLocal 15 def getXXXTimeFormat2(name, place): 16 curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) 17 return f'{curTime} ,数据采集者:{name} , 采集地:{place}' 18 19 print(getXXXTimeFormat1('张三')) 20 print(getXXXTimeFormat2('张三',place='北京')) 21 22 # 运行结果 23 当地时间: 2020-04-14 21:10:49 ,数据采集者:张三 24 当地时间: 2020-04-14 21:10:49 ,数据采集者:张三 , 采集地:北京
多个装饰器装饰同一个函数:
1 def add_auth(func): 2 print("---开始进行装饰权限1的功能---") 3 def call_func(*args, **kwargs): 4 print("---这是权限验证1---") 5 return func(*args, **kwargs) 6 return call_func 7 8 def set_func(func): 9 print("---开始进行装饰权限2的功能---") 10 def call_func(*args, **kwargs): 11 print("---这是权限验证2---") 12 return func(*args, **kwargs) 13 return call_func 14 # return call_func() 15 16 @add_auth 17 @set_func 18 def demo(): 19 print("----test1----") 20 21 demo()
运行结果:
1 ---开始进行装饰权限2的功能--- 2 ---开始进行装饰权限1的功能--- 3 ---这是权限验证1--- 4 ---这是权限验证2--- 5 ----test1----
从运行结果可以看出:
- 越靠近原函数的装饰器(代码从上往下,原函数上最后一个@符后的名称)越先装饰
- 越远离原函数的装饰器越先执行,装饰器都执行完成之后再执行原函数
- 多个装饰器装饰同一个函数相当于给原函数包多层,先执行的包住后执行的,最后包住原函数执行的代码。
类装饰器:
1 class Test(object): 2 3 def __init__(self, func): 4 self.func = func 5 6 def __call__(self, *args, **kwargs): 7 print("这是装饰器添加的功能......") 8 return self.func(*args, **kwargs) 9 10 11 @Test 12 def get_str(): 13 return '哈哈哈' 14 15 print(get_str())
运行结果:
1 这是装饰器添加的功能...... 2 哈哈哈