python的装饰器本质是函数,为了不改变装饰目标函数内部代码而增加额外功能而存在
一.一般装饰函数实例:
import datetime def func_name(func):#定义一个装饰函数,接受一个函数对象作为参数(也就是被装饰的函数) def wrap():#包装函数 print("Function name:%s"%(func.__name__)) func() #执行目标函数 return wrap #返回包装函数 @func_name #等于 func_time = func_name(func_time) def func_time(): #目标函数 print(datetime.datetime.now()) func_time() #执行结果: Function name:func_time 2017-09-22 17:25:30.622356
二.带参数的装饰函数
装饰器本身可以带参数,我们来给装饰器增加一个是否要输出函数名的参数is_show,不用管那函数有多少个参数。使用Python的可变参数 *args
和关键字参数 **kwargs
即可
import datetime def func_name(is_show=True):#定义一个带有参数的装饰函数 def wrap(func):#包装函数,接受一个函数对象作为参数 def inner_wrap(*args,**kwargs): if is_show: print("Function name:%s"%(func.__name__)) return func(*args,**kwargs) return inner_wrap return wrap @func_name(True) #显示函数名 def func_time1(): print(datetime.datetime.now()) @func_name(False) #不显示函数名 def func_time2(): print(datetime.datetime.now()) func_time1() func_time2() #执行结果: Function name:func_time1 2017-09-22 18:41:49.695787 2017-09-22 18:41:49.696288
总结
1.定义一个装饰器函数,此函数会接受函数对象作为输入参数,以确保能执行其功能
2.在装饰器函数内定义一个和目标函数参数列表一致的包装函数,返回值(包装函数),同时添加欲追加的工作量(甚至彻底替换掉目标函数)
3.装饰器函数返回值设置为包装函数
4.把目标函数对象传递给装饰器函数去执行,返回值(包装函数)赋值到目标函数名上,最后以目标函数之名调用包装函数