一、單個裝飾器執行python
上來先看代碼:app
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"
再看執行結果:函數
由此咱們能夠看出,裝飾器執行順序爲主線程——》裝飾器,裝飾器中調用了被裝飾函數的話就在裝飾器中依次執行。線程
二、多個裝飾器執行code
被裝飾函數被多個裝飾器裝飾時,代碼以下:blog
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繼續執行。class
這就能夠回到裝飾器的原理來看:import
裝飾器是在編譯時就執行,而不是調用時;裝飾器只對函數進行裝飾,不對裝飾器進行裝飾,誰貼函數進誰先執行。原理
多個裝飾器執行的例子,就至關於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裝飾器相同。