一、基础使用介绍
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
python中的装饰器(decorator)一般采用语法糖的形式,是一种语法格式。比如:@classmethod,@staticmethod,@property,@xxx.setter,@wraps(),@func_name等都是python中的装饰器。
装饰器,装饰的对象是函数或者方法。各种装饰器的作用都是一样的:改变被装饰函数或者方法的功能,性质。
# 为函数添加一个统计运行时长的功能 import time def how_much_time(func): def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner # 将增加的新功能代码以及被装饰函数运行代码func()一同打包返回,返回的是一个内部函数,这个被返回的函数就是装饰器 def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) def sleep_6s(): time.sleep(6) print("%d秒结束了" % (6,)) sleep_5s = how_much_time(sleep_5s) # 因为sleep_5s函数的功能就是睡5秒钟,虽然增加了统计运行时间的功能,但是他本身功能没变(还是睡5秒钟),所以仍然用原来函数名接收增加功能了的自己 sleep_6s = how_much_time(sleep_6s) t1 = threading.Thread(target=sleep_5s) t2 = threading.Thread(target=sleep_6s) t1.start() t2.start() # 5秒结束了 # 一共花费了5.014161109924316秒时间 # 6秒结束了 # 一共花费了6.011810302734375秒时间
# 为函数添加一个统计运行时长的功能 import time import threading def how_much_time(func): def inner(): t_start = time.time() func() t_end = time.time() print("一共花费了{0}秒时间".format(t_end - t_start, )) return inner @how_much_time # @how_much_time等价于sleep_5s = how_much_time(sleep_5s) def sleep_5s(): time.sleep(5) print("%d秒结束了" % (5,)) @how_much_time def sleep_6s(): time.sleep(6) print("%d秒结束了" % (6,)) t1 = threading.Thread(target=sleep_5s) t2 = threading.Thread(target=sleep_6s) t1.start() t2.start()
sleep_5s = how_much_time(sleep_5s)-----》为内置函数,已经被装饰了。其中内置函数的参数最好和被装饰函数参数一致。如果我们还想让他保持原有名字,在内置函数上(外部函数返回内置函数)协商装饰器:@functools.wraps(func)
二、装饰器模板
import functools def outer(origin): @functools.wraps(origin) def inner(*args, **kwargs): # 这里书写需要装饰的功能 res = origin(*args, **kwargs) # 这里书写需要装饰的功能 return res return inner
记得要在需要装饰的函数前要写上@outer
三、装饰器高级使用
三层函数:
def outter(x,y): def handle_action(fn): def do_action(arg1,arg2,*args,**kwargs): #被装饰函数执行前代码 fn(arg1,arg2,*args,**kwargs) #被装饰函数执行后代码 return do_action return handle_action @outter(x,y) def fn(arg1,arg2,*args,**kwargs): pass
""" 当user_permission = 13 = 1101,即有exe、read、delete权限 user_permission和操作权限码进行与运算,只要不为0,则具有相应权限可以执行被装饰函数 例如user_permission = 13 = 1101,没有写的权限,WRITE_PERMISSION = 2 # 0010 1101 & 0010 = 0 """ user_permission = 13 # 1101 DEL_PERMISSION = 8 # 1000 READ_PERMISSION = 4 # 0100 WRITE_PERMISSION = 2 # 0010 EXE_PERMISSION = 1 # 0001 def check_pomission(x, y): def handle_action(fn): def do_action(): if x & y: fn() return do_action return handle_action @check_pomission(user_permission, READ_PERMISSION) def read(): print('我正在读内容') @check_pomission(user_permission, WRITE_PERMISSION) def write(): print('我正在写内容') @check_pomission(user_permission, DEL_PERMISSION) def delete(): print('我正在删内容') @check_pomission(user_permission, EXE_PERMISSION) def exe(): print('我正在执行内容') read() write() delete() exe() """ 我正在读内容 我正在删内容 我正在执行内容 """