標籤:rtti 重複執行 python裝飾器 his 執行 a+b 參數 test print
簡言之,python裝飾器就是用於拓展原來函數功能的一種函數,這個函數的特殊之處在於它的傳回值也是一個函數,使用python裝飾器的好處就是在不用更改原函數的代碼前提下給函數增加新的功能。
我們先實現一個最簡陋的裝飾器,不使用任何文法糖和進階文法,看看裝飾器最原始的面貌:
#既不需要侵入,也不需要函數重複執行,不需改動func()代碼import timedef deco(func): def wrapper(): startTime = time.time() func() endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decodef func(): print("hello") time.sleep(1) print("world")if __name__ == ‘__main__‘: f = func #這裡f被賦值為func,執行f()就是執行func() f()
這裡的deco函數就是最原始的裝飾器,它的參數是一個函數,然後傳回值也是一個函數。其中作為參數的這個函數func()就在返回函數wrapper()的內部執行。然後在函數func()前面加上@deco,func()函數就相當於被注入了計時功能,現在只要調用func(),它就已經變身為“新的功能更多”的函數了。
所以這裡裝飾器就像一個注入符號:有了它,拓展了原來函數的功能既不需要侵入函數內更改代碼,也不需要重複執行原函數。
#帶有參數的裝飾器import timedef deco(func): def wrapper(a,b): startTime = time.time() func(a,b) endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decodef func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b))if __name__ == ‘__main__‘: f = func f(3,4) #func()
#帶有不定參數的裝飾器import timedef deco(func): def wrapper(*args, **kwargs): startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) return wrapper@decodef func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b))@decodef func2(a,b,c): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b+c))if __name__ == ‘__main__‘: f = func func2(3,4,5) f(3,4) #func()
#多個裝飾器import timedef deco01(func): def wrapper(*args, **kwargs): print("this is deco01") startTime = time.time() func(*args, **kwargs) endTime = time.time() msecs = (endTime - startTime)*1000 print("time is %d ms" %msecs) print("deco01 end here") return wrapperdef deco02(func): def wrapper(*args, **kwargs): print("this is deco02") func(*args, **kwargs) print("deco02 end here") return wrapper@deco01@deco02def func(a,b): print("hello,here is a func for add :") time.sleep(1) print("result is %d" %(a+b))if __name__ == ‘__main__‘: f = func f(3,4) #func()‘‘‘this is deco01this is deco02hello,here is a func for add :result is 7deco02 end heretime is 1003 msdeco01 end here‘‘‘
多個裝飾器執行的順序就是從最後一個裝飾器開始,執行到第一個裝飾器,再執行函數本身。
盜用評論裡面一位童鞋的例子:
def dec1(func): print("1111") def one(): print("2222") func() print("3333") return one def dec2(func): print("aaaa") def two(): print("bbbb") func() print("cccc") return two @dec1 @dec2 def test(): print("test test") test()
輸出:
aaaa 1111 2222 bbbb test test cccc 3333
python裝飾器詳解