python 函式裝飾 Python 函式裝飾器

2021-10-18 14:01:09 字數 2842 閱讀 3929

首次接觸到裝飾器的概念,太菜啦!

python 裝飾器可以大大節省**的編寫量,提公升**的重複使用率。函式裝飾器其本質也是乙個函式,我們可以把它理解為函式中定義了乙個子函式。

例如我們有這麼乙個需求,每次執行乙個函式後,需要知道這個函式執行了多長時間。一般情況下,我會這樣寫:

defaccumulate(n):"""accumulate number which is from 1 to n"""s=0;for i in range(1,n+1):

s= s +i;returns;importtime;

start=time.time();

result= accumulate(1000000);

end=time.time();print("funtion run time %.5f" % (end - start));

問題來了,如果又來了乙個函式呢?重複上面的**嗎?天啦嚕,來一百個函式豈不玩完了。這個時候就要用到裝飾器了,將於具體函式功能不相關的內容全部寫進裝飾器中,這樣一來,附加功能與函式功能就能完全分離。提公升**的使用率。

deffunctionruntime(func):def warper(*args,**kwargs):

start=time.time();

result= func(*args,**kwargs);

end=time.time();print("function run time %.5f" % (end -start));returnresult;returnwarper;

@functionruntimedefaccumulate(n):"""accumulate number which is from 1 to n"""s=0;for i in range(1,n+1):

s= s +i;return s;

result = accmulate(1000000);

如此一來,列印函式執行時間的部分就實現了重用。如果在來乙個函式,只需在函式宣告時加上@functionruntime 即可。如果不想這麼寫還可以有另外一種寫法,因為裝飾器本質上是乙個函式,可以使用函式傳參的方式將裝飾器加到目標函式上。

acc =functionruntime(accumulate);

result= acc(100000);

這樣的話就降低了**的可讀性,最好還是用@符,清爽,不產生語義偏差。

如果函式是乙個遞迴函式呢?因為裝飾器是將函式包裹起來的外層函式,也就是說裝飾器和函式執行次數一樣多。如果函式是遞迴函式,那麼裝飾器是不是也同樣執行多次呢?帶著這個問題,做一下實驗。

實驗結果說明,裝飾器也同樣執行多次。那麼這個問題如何解決呢?還是回歸到裝飾器的特點上來說。裝飾器本質是乙個函式,而且是將目標函式包裹起來,它只與目標函式有關。現在的問題是目標函式是遞迴執行多次,所起裝飾器也執行多次。如果將目標函式從遞迴函式變成非遞迴函式不就將問題解決了嗎?如何實現這個轉換又成為了另乙個問題。解決方法很巧妙,我們只需要在目標函式外在套一層函式,讓具有遞迴特性的函式成為乙個子函式,那麼它就不再是裝飾器包裹的物件了。

從函式上來看,此時的fib 函式就是乙個普通的函式,不具有遞迴特性。

裝飾器的一些小問題

裝飾器既然也是函式,那麼就可以傳參。通過傳遞引數可以使裝飾器實現更加複雜的功能。

被裝飾器裝飾後的函式已經不再是它自己。使用@符很好的規避了語義上的差異,使程式的可讀性保持不變,但要深入理解裝飾器還得看其執行過程。回到不帶引數的裝飾器那個例子。accumulate 實際上是accumulate = functionruntime(accumulate); 此時的accumulate 其實是warper 函式。下面看個簡單的驗證。

所以,真實的情況是accumulate 是warper 的函式控制代碼,只不過名稱叫accumulate 讓我們在視覺上覺得它還是原來的accumulate ,極具迷惑性。

在大牛的肩膀上跳躍。

參考文獻

python 函式裝飾 Python 函式裝飾器

無引數的 函式裝飾器 funa 作為裝飾器函式 def funa fn print sakura func a fn 執行傳入的fn引數 print sakura second return sakura return funa def funb print sakurab 返回結果為 sakura...

python 裝飾函式

此文的最後乙個蛋疼的例子可以幫助理解這個概念,錯誤寫法 def warp fun print fun print warp def myprint print lalala myprint 這句並沒有卵用,刪掉這句也會有輸出,輸出是由 warp這句列印的 print myprint none 正確的...

python函式裝飾函式 Python函式裝飾器

本文來介紹一下python的函式裝飾器,類裝飾器以後另開一文講。裝飾器可以看做是python中的乙個語法糖,基本的寫法示例如下 defdecorator func returnfunc decoratordeffunction print 666 decorator即是function的裝飾器,在f...