一、概念:
从本质上讲,装饰器(B)本身就是一个函数,它的功能是用来装饰已经定义好的原函数(A)(也可以理解成为已经定义好的原函数添加一些附加的功能)。
二、原则:
1.不能修改A的源代码;
2.不能修改A的调用方式。
一句话,B对A是完全透明的,即A不知道B对A进行过附加修饰。
实现一个最简陋的装饰器,不使用任何语法糖和高级语法,看看装饰器最原始的面貌:
#既不需要侵入,也不需要函数重复执行
import time
def deco(func):
def wrapper():
startTime = time.time()
func()
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func():
print("hello")
time.sleep(1)
print("world")
if __name__ == '__main__':
f = func #这里f被赋值为func,执行f()就是执行func()
f()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数func()就在返回函数wrapper()的内部执行。然后在函数func()前面加上@deco,func()函数就相当于被注入了计时功能,现在只要调用func(),它就已经变身为“新的功能更多”的函数了。
所以这里装饰器就像一个注入符号:有了它,拓展了原来函数的功能既不需要侵入函数内更改代码,也不需要重复执行原函数。
使用了”@”语法糖后,我们就不需要额外代码来给”func”重新赋值了,其实”@deco”的本质就是”func = deco(func)”,当认清了这一点后,后面看带参数的装饰器就简单了。