装饰器小记
1.什么是装饰器
装饰器,顾名思义在不改变原函数代码和调用方式的情况下,为函数增加一些新功能.
装饰器的本质其实就是闭包
假如现在有一个index函数如下:
import time def index(): time.sleep(2) print('欢迎登录博客园首页')
现在你要测试函数的运行时间,怎么在不改变函数源码的情况下改变呢
首先你可能会这样做:
def timmer(f): def inner(): start_time = time.time() f() end_time = time.time() print('函数运行使用了{}时间'.format(end_time-start_time)) return inner index = timmer(index) index()
在这种方法中,index函数代码没有改变,调用方式也没改变,可以测试其运行速度,但是假如index函数有返回值呢?
比如这样:
import time
def index(): time.sleep(2) print('欢迎登录博客园首页') return 666
这样的话执行index()函数返回值为none,但是装饰器不应该改变函数返回值666
那么就应该这样做:
def timmer(f): def inner(): start_time = time.time() r = f() end_time = time.time() print('函数运行使用了{}时间'.format(end_time-start_time)) return r return inner
上面的做法比较完整但是没有考虑传参问题,标准版装饰器格式如下:
需要装饰那个函数就在函数上面加@装饰器函数名,这里是@timmer
def wrapper(f): ''' 添加额外的功能,执行被装饰函数之前的操作 :param f: 被装饰函数的函数名 :return: ''' def inner(*args,**kwargs): ''' :param args: 形参加*,表示聚拢位置参数 :param kwargs: 表示聚拢关键字参数 :return: 被装饰函数的返回值 ''' ret = f(*args,**kwargs) ''' 添加额外的功能,执行被装饰函数之后的操作 ''' return ret return inner()
完整版装饰器,例子如下:
import time def timmer(f): def inner(*args,**kwargs): ''' 假如inner('老虎','12'),位置参数,*args把参数聚拢成元组('老虎','12') :param args: :param kwargs: :return: ''' start_time =time.time() #f作为被调用的函数传入的是实参,实参里的*,**起到打散的作用 ret = f(*args,**kwargs) end_time = time.time() print('函数执行的时间为{}'.format(end_time-start_time)) return ret return inner @timmer def dairy(name,age): time.sleep(0.5) print('%s的年龄是%s'%(name,age)) return 666 dairy('老王',16)

浙公网安备 33010602011771号