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裝飾器相同。