装饰器
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后的清理功能
- 权限校验等场景
- 缓存
装饰器其实是一个函数。作用就是为已经存在的函数或对象添加额外的功能,并且函数或对象不需要做任何改变。
import time
def logger(fun): #logger就是一个装饰器
def inner(): #闭包
print(time.ctime(time.time()))
fun()
return inner #必须要返回inner函数,而不是inner函数执行结果
@logger #相等于summation=logger(summation),logger(summation)的执行结果为inner
def summation():
summs = 10 + 20
print(summs)
summation()
#执行结果
Sun Apr 28 15:48:30 2019
30
summation是两个常数求和的函数,logger是一个将函数作为参数fun的装饰器函数,其中封装了一个拥有外部环境的inner函数,函数中打印当前时间并执行参数fun,然后将inner函数返回;如果想在执行summation函数前打印当前时间,就可以直接将summation函数当作参数放入logger函数中运行,即logger(summation),再将执行结果赋值给summation,即summation=logger(summation),这样summation函数中的代码内容没有发生变化,调用方式也没有发生变化,还是summation();python中简单规范的写法为@logger。这样的作用是以后在生产中,可以想要增加一些通用的功能,也不会影响到其他同事对此函数的调用方式。
函数带参数的装饰器
针对代码增加一个需求,可以自定义对哪些数值进行求和,那么就需要在summation中加入参数,相应的装饰器也必须增加同样的参数;
import time
def logger(fun):
def inner(*args): #在这儿引入参数到局部作用域中,fun()才可以引用参数,
print(time.ctime(time.time()))
fun(*args) #如果传入的fun带有参数,这儿fun执行也必须带有参数
return inner
@logger #summation=logger(summation)=inner
def summation(*args): #添加可变参数
summs = 0
for i in args:
summs += i
print(summs)
summation(1,2,3,4,5)
#执行结果
Sun Apr 28 16:28:54 2019
15
装饰器带有参数
也可以针对装饰器添加参数,只需要再向外嵌套一层。
import time
def show_time(is_show):
def logger(fun):
def inner(*args):
if is_show == 'asc':
print(time.ctime(time.time())) #以可读模式显示
elif is_show == 'no':
print('no display time') #不显示
else:
print(time.time()) #以秒显示
fun(*args)
return inner
return logger
@show_time('no') #传入参数'no'
def summation(*args):
summs = 0
for i in args:
summs += i
print(summs)
summation(1,2,3,4,5)
#执行结果
no display time
15