1、单个装饰器执行
上来先看代码:
import time
def deco(func):
@functools.wraps(func)
def _wrapper():
startTime = time.time()
print "start"
func()
print "end"
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__':
print "main start"
f = func
print "mid"
f()
print "main end"
再看执行结果:
由此我们可以看出,装饰器执行顺序为主线程——》装饰器,装饰器中调用了被装饰函数的话就在装饰器中依次执行。
2、多个装饰器执行
被装饰函数被多个装饰器装饰时,代码如下:
import time
def deco1(func):
@functools.wraps(func)
def _wrapper():
startTime = time.time()
print "start1"
func()
print "end1"
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time1 is %d ms" %msecs)
return _wrapper
def deco(func):
@functools.wraps(func)
def _wrapper():
startTime = time.time()
print "start"
func()
print "end"
endTime = time.time()
msecs = (endTime - startTime)*1000
print("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 = func
print "mid"
f()
print "main end"
运行结果如下:
可以看到,先执行了deco,再执行deco1,然后deco1执行完返回结果作为参数传入deco继续执行。
这就可以回到装饰器的原理来看:
装饰器是在编译时就执行,而不是调用时;装饰器只对函数进行装饰,不对装饰器进行装饰,谁贴函数进谁先执行。
多个装饰器执行的例子,就相当于func = deco1(func), func = deco(func), func() 这也等同于func = deco(deco1(func)), func()。
例如:
import time
def deco1(func):
@functools.wraps(func)
def _wrapper():
startTime = time.time()
print "start1"
func()
print "end1"
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time1 is %d ms" %msecs)
return _wrapper
def deco(func):
@functools.wraps(func)
def _wrapper():
startTime = time.time()
print "start"
func()
print "end"
endTime = time.time()
msecs = (endTime - startTime)*1000
print("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装饰器相同。