一、装饰器的含义
装饰是指将一个函数传递给装饰器,让装饰器在返回被传入函数之前,对被传入函数执行的一系列操作。通常用于日志记录等比较复杂的环境。
二、最直接的装饰器
为了记录一个函数的使用开始时间和结束时间,我们直接在函数中添加代码:
import time
def func():
#添加部分
startTime = time.time()
#函数开始
print("hello")
time.sleep(1)
print("world")
#函数结束
#添加部分
endTime = time.time()
m = endTime - startTime
print("time is %d ms" %m)
三、改进的装饰器方式
但是如果我们需要不同种类的记录而不仅仅是时间的记录,我们是是不是又要重写函数呢。为了避免函数的重写,我们使用函数来包裹装饰器,使其耦合性更低。
import time
def func():
#函数开始
print("hello")
time.sleep(1)
print("world")
#函数结束
def record_time():
#添加部分
startTime = time.time()
func()
#添加部分
endTime = time.time()
m = endTime - startTime
print("time is %d ms" %m)
def record_xxx():
#添加部分
#...
func()
#...
#添加部分
if __name__ == '__main__':
f = func
record_time(f)#只有把func()或者f()作为参数执行,新加入功能才会生效
print("f.__name__ is",f.__name__)#f的name就是func()
print()
这样的话是不是我们就将函数和用于记载时间的函数和用于记载其他事件的函数分开了,减少了重写函数的代码量。
四、python的装饰器
为了更加简化,我们可以使用Python的装饰器来解决以上问题:
#既不需要侵入,也不需要函数重复执行
import time
def record_time(func):
def wrapper():
startTime = time.time()
func()
endTime = time.time()
m = endTime - startTime
print("time is %d m" %m)
return wrapper
##装饰器的名称
@record_time
def func():
print("hello")
time.sleep(1)
print("world")
if __name__ == '__main__':
f = func #这里f被赋值为func,执行f()就是执行func()
f()
以上函数与上面得到的结果是一样的。在使用python装饰器后,代码得到了极大的简化,不用再关注装饰类型
五、多参数的python装饰器
但是上面函数该如何使用带有参数的函数呢?以下是示例:
#带有参数的装饰器
import time
def record_time(func):
#使用wrapper参数带入
def wrapper(a,b):
startTime = time.time()
func(a,b)
endTime = time.time()
m = endTime - startTime
print("time is %d m" %m)
return wrapper
@record_time
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f = func
f(3,4)
#func()
六、带有不定参数的代码示例
为了更加完善代码,我们使用*args和**kwargs来解决
#带有不定参数的装饰器
import time
def record_time(func):
#不定参数记录
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@record_time
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
@record_time
def func2(a,b,c):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b+c))
if __name__ == '__main__':
f = func
func2(3,4,5)
f(3,4)
#func()
七、加入多个装饰器
为了更加丰富装饰器,我们可以使用多个装饰器来装饰函数:
#多个装饰器
import time
def record_time(func):
def wrapper(*args, **kwargs):
print("this is deco01")
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
print("record_time end here")
return wrapper
def record2(func):
def wrapper(*args, **kwargs):
print("this is record2")
func(*args, **kwargs)
print("record2 end here")
return wrapper
@deco01
@deco02
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
if __name__ == '__main__':
f = func
f(3,4)
#func()
'''
this is record_time
this is record2
hello,here is a func for add :
result is 7
record2 end here
time is 1003 ms
record_time end here
'''