2019独角兽企业重金招聘Python工程师标准>>>
1、单个装饰器执行
上来先看代码:
import timedef deco(func):@functools.wraps(func)def _wrapper():startTime = time.time()print "start"func()print "end"endTime = time.time()msecs = (endTime - startTime)*1000print("time is %d ms" %msecs)return _wrapper@deco
def func():print("hello")time.sleep(1)print("world")if __name__ == '__main__':print "main start"f = func print "mid"f()print "main end"
再看执行结果:
由此我们可以看出,装饰器执行顺序为主线程——》装饰器,装饰器中调用了被装饰函数的话就在装饰器中依次执行。
2、多个装饰器执行
被装饰函数被多个装饰器装饰时,代码如下:
import timedef deco1(func):@functools.wraps(func)def _wrapper():startTime = time.time()print "start1"func()print "end1"endTime = time.time()msecs = (endTime - startTime)*1000print("time1 is %d ms" %msecs)return _wrapperdef deco(func):@functools.wraps(func)def _wrapper():startTime = time.time()print "start"func()print "end"endTime = time.time()msecs = (endTime - startTime)*1000print("time is %d ms" %msecs)return _wrapper@deco
@deco1
def func():print("hello")time.sleep(1)print("world")if __name__ == '__main__':print "main start"f = funcprint "mid"f()print "main end"
运行结果如下:
可以看到,先执行了deco,再执行deco1,然后deco1执行完返回结果作为参数传入deco继续执行。
这就可以回到装饰器的原理来看:
装饰器是在编译时就执行,而不是调用时;装饰器只对函数进行装饰,不对装饰器进行装饰,谁贴函数进谁先执行。
多个装饰器执行的例子,就相当于func = deco1(func), func = deco(func), func() 这也等同于func = deco(deco1(func)), func()。
例如:
import timedef deco1(func):@functools.wraps(func)def _wrapper():startTime = time.time()print "start1"func()print "end1"endTime = time.time()msecs = (endTime - startTime)*1000print("time1 is %d ms" %msecs)return _wrapperdef deco(func):@functools.wraps(func)def _wrapper():startTime = time.time()print "start"func()print "end"endTime = time.time()msecs = (endTime - startTime)*1000print("time is %d ms" %msecs)return _wrapper# @deco
# @deco1
def func():print("hello")time.sleep(1)print("world")if __name__ == '__main__':print "main start"func = deco(deco1(func)) #编译func() #执行print "mid"print "main end"
执行结果和使用deco,deco1装饰器相同。