本文實例講述了Python裝飾器原理與簡單用法。分享給大家供大家參考,具體如下:
今天整理裝飾器,內嵌的裝飾器、讓裝飾器帶參數等多種形式,非常復雜,讓人頭疼不已。但是突然間發現了裝飾器的奧秘,原來如此簡單。。。。
第一步 :從最簡單的例子開始
# -*- coding:gbk -*-'''示例1: 使用語法糖@來裝飾函數,相當于"myfunc = deco(myfunc)"但發現新函數只在第一次被調用,且原函數多調用了一次'''def deco(func): print("before myfunc() called.") func() print(" after myfunc() called.") return func@decodef myfunc(): print(" myfunc() called.")myfunc()myfunc()這是一個最簡單的裝飾器的例子,但是這里有一個問題,就是當我們兩次調用myfunc()的時候,發現裝飾器函數只被調用了一次。為什么會這樣呢?要解釋這個就要給出破解裝飾器的關鍵鑰匙了。
這里@deco這一句,和myfunc = deco(myfunc)其實是完全等價的,只不過是換了一種寫法而已
一定要記住上面這句!!!!
好了,從現在開始,只需要做替換操作就可以了。
將@deco 替換為 myfunc = deco(myfunc)
程序首先調用deco(myfunc),得到的返回結果賦值給了myfunc (注意:在Python中函數名只是個指向函數首地址的函數指針而已)
而deco(myfunc)的返回值就是函數myfunc()的地址
這樣其實myfunc 沒有變化,也就是說,最后的兩次myfunc()函數調用,其實都沒有執行到deco()。
有同學就問了,明明打印了deco()函數里面的內容啊,怎么說沒有調用到呢。這位同學一看就是沒有注意聽講,那一次打印是在@deco 這一句被執行的。大家親自動手試一下就會發現" myfunc() called." 這句打印輸出了三次。多的那次就是@deco這里輸出的,因為@deco 等價于myfunc = deco(myfunc),這里已經調用了deco()函數了。
第二步 :確保裝飾器被調用
怎么解決裝飾器沒有被調用的問題呢
# -*- coding:gbk -*-'''示例2: 使用內嵌包裝函數來確保每次新函數都被調用,內嵌包裝函數的形參和返回值與原函數相同,裝飾函數返回內嵌包裝函數對象'''def deco(func): def _deco(): print("before myfunc() called.") func() print(" after myfunc() called.") # 不需要返回func,實際上應返回原函數的返回值 return _deco@decodef myfunc(): print(" myfunc() called.") return 'ok'myfunc()myfunc()這里其實不需要我解釋了,還是按照第一步中的方法做替換就可以了。還是啰嗦幾句吧。。
@deco 替換為 myfunc = deco(myfunc)
程序首先調用deco(myfunc),得到的返回結果賦值給了myfunc ,這樣myfunc 就變成了指向函數
新聞熱點
疑難解答