一,为何要有装饰器
根据开放封闭原则得来
1,开放:
指的是对扩展功能是开放的(可以扩展功能)
2,封闭:
指的是对修改源码是封闭的(不可对源代码进行修改,调用方式不能变)
二,根据以上原则进行推导
1,定义一个函数: (导入ttime,使用time.sleep是为了模仿程序运行耗用时间)
import time
def func(x, y):
time.sleep(2)
print('print %s %s' % (x, y))
func(1, 2)
运行之后:
print 1 2
2,增加一个需求:计算程序运行时间
方式①
def func(x, y):
start=time.time()
time.sleep(2)
print('print %s %s' % (x, y))
stop=time.time()
print(stop-start)
func(1, 2)
运行之后
```
print 1 2
2.0160648822784424
```
总结:方式①修改了源代码,不可使用这种方法
方式②
def func(x, y):
time.sleep(2)
print('print %s %s' % (x, y))
def wrapper(x,y):
start=time.time()
func(x,y)
stop=time.time()
print(stop-start)
wrapper(1,2)
总结:没有在原代码上修改,但是func写死了(以后换成其他的函数,自己要手动改)
改进方式②
def func(x, y):
time.sleep(2)
print('print %s %s' % (x, y))
def outter(function):
def wrapper(x,y):
start=time.time()
function(x,y) # 防止写死,可以直接传入要装饰的函数
stop=time.time()
print(stop-start)
return wrapper
func = outter(func) # 执行outter(func)---》返回值 wrapper(wrapper的内存地址)
func(1, 2) #未改变调用方式
运行之后
print 1 2
2.0280213356018066
3,语法糖概念@
def outter(function):
def wrapper(x,y):
start=time.time()
function(x,y)
stop=time.time()
print(stop-start)
return wrapper
@outter # func=outter(func)
def func(x, y):
time.sleep(2)
print('print %s %s' % (x, y))
func(1,3)
运行之后
print 1 3
2.000622272491455