任務1:給兩個函數寫一個裝飾器,用來統計這兩個函數各自的執行時間。
先看代碼:
運行結果:
test1()和test2()是兩個普通的函數,它們均各自有各自的邏輯。temer()為裝飾器,就是為了給test1()和test2()添加計算運算時間的功能。
@timer 需要放在你要裝飾的函數的前面,假如放在test1()函數的前面,那麼它就相當於test1 = timer(test1)
調用test1(),其實test1 = timer(test1),而這個time()它返回的是一個deco()函數的地址,而在deco()就有統計函數運行時間的方法。這樣我們就實現了既沒有改變被修飾函數也沒有改變被修飾函數的調用方式而給它添加了新的功能,這就是裝飾器的魅力。
任務2:怎麼製作一個裝飾器裝飾帶有參數的函數
先看一個報錯 的代碼:我們現在改動一下上一個程序
報錯信息:
我只是把test2()這個函數加了一個參數,然後還是使用timer這個裝飾器,明顯報錯了,提示我丟失一個未知參數name
我們來分析一下:
test2()的這個@timer,它相當於test2 = timer(test2) = deco
那麼給test2()就相當於deco()那麼調用其實就這deco()。那麼運行deco(),那麼運行裡面的func()就是運行test2()。func()沒有傳參數了啊,那對於test2報錯就是必然的呢。沒有傳參數的test1,是不會報錯的。那麼怎麼傳這個參數呢?
那其實也很簡單了,我們給deco()傳入一個參數就好了。
同樣的方法,你傳入兩個或多個參數也可以的,但是,這樣的話,我們的test1用這個裝飾器又報錯了,因為test1()是一個沒有參數傳入的函數。那麼我們怎麼來滿足,可能有時候有采參數,有時候沒有參數這種普遍情況呢?
所以裝飾器應該傳入的是非固定參數。代碼如下:
輸出:
這就比較完美的解決了,被裝飾的函數的參數傳入的問題了。不管你有沒有參數,或是有幾個參數。這個裝飾器變的更通用了。
任務3:怎麼去裝飾一個帶有返回值的函數
我們下來看這樣一個例子:假如現在你要去寫幾個網頁,其中有幾個網頁是需要用戶登錄的,有的是不需要用戶登錄的。我們需要這麼寫:
運行結果:
我們發現到目前為止,我們的被裝飾的函數都沒有返回任何的值,我們來試試我們返回一個值:
看一下結果:
問題來了:沒有返回數據。那這就不叫一個裝飾器了,裝飾器滿足的條件我們前面說到過。具體見《 》裝飾器是不能改變我原函數的。其實這個地方理解也很簡單,
這個地方是沒有返回的啊,那肯定沒有數據了。那就加一個返回唄,試試:
看看結果:
數據還真來了。但是有這樣的一個問題,現在我是把用戶名和密碼寫死的,那麼怎麼實現一個靈活的認證呢?
我們讓home使用本地認證,bbs使用ldap認證。
那就在裝飾器這邊加參數就好了:
那麼裝飾器就得在添加一層函數了:
這是不是就厲害了。
閱讀更多 小5嵌入式 的文章