您好,登錄后才能下訂單哦!
小編給大家分享一下python的修飾器是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
python的修飾器本質上是一個python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,修飾器的返回值是一個函數對象。
裝飾器是一個很著名的設計模式,經常被用于有切面需求的場景,較為經典的有插入日志、性能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函數中與函數功能本身無關的雷同代碼并繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。
功能
我們首先從一個簡單的例子說起,這個例子是stackflow上的一個問題,如何通過使用如下的代碼實現輸出<b><i>Hello</i></b>:
@makebold @makeitalic def say(): return "Hello"
先看一下答案:
def makebold(fn): def wrapped(): return "<b>" + fn() + "</b>" return wrapped def makeitalic(fn): def wrapped(): return "<i>" + fn() + "</i>" return wrapped @makebold @makeitalic def hello(): return "hello world" print hello() #返回 <b><i>hello world</i></b>
這里的@makebold和@makeitalic似乎給Hello加上了一層包裝(or修飾),這就是修飾器最明顯的體現。
從需求談起
初期,我寫了一個函數
def foo(): print 'in foo()' foo()
為了檢查這個函數的復雜度(在網絡編程中程序的延時還是很重要的),需要測算運算時間,增加了計算時間的功能有了下面的代碼:
import time def foo(): start = time.clock() print 'in foo()' end = time.clock() print 'Time Elapsed:', end - start foo()
這里只是寫了一個函數,如果我想測量多個函數的延時,由于必須知道start與end,所以必須寫在程序的開頭與結尾,難道每一個程序都這樣復制粘貼么?固然可行,但是,我們可以通過設計模式中將功能與數據部分分離一樣,將這個測量時間的函數分離出去,就像C++中我們可以將這個測量時間的函數變為一個類,通過調用這個類,賦予不同的函數來測量不同的函數的運行時長。在python中,由于函數實際上就是對象,所以可以利用類似的方法實現:
import time def foo(): print 'in foo()' def timeit(func): start = time.clock() func() end =time.clock() print 'Time Elapsed:', end - start timeit(foo)
這里func()就可以指定函數了,但是如果我不想填這個函數或者這個功能函數并不能修改成類似的形式怎么辦?我們需要的是最大限度的少改動:
import time def foo(): print 'in foo()' # 定義一個計時器,傳入一個,并返回另一個附加了計時功能的方法 def timeit(func): # 定義一個內嵌的包裝函數,給傳入的函數加上計時功能的包裝 def wrapper(): start = time.clock() func() end =time.clock() print 'Time Elapsed:', end - start # 將包裝后的函數返回 return wrapper foo = timeit (foo) #可以直接寫成@timeit + foo定義,python的"語法糖"foo() #在這個代碼中,timeit(foo)不是直接產生調用效果,而是返回一個與foo參數列表一致的函數,此時此foo非彼foo!因為此時的foo具有了timeit的功效,簡單來說就是能夠讓你在裝飾前后執行代碼而無須改變函數本身內容,裝飾器是一個函數,而其參數為另外一個函數。 #一個有趣的"漢堡"讓你了解順序 #順序在修飾器還是非常重要的,利用一個代碼展示一下: def bread(func) : def wrapper() : print "</''' '''\>" func() print "<\______/>" return wrapper def ingredients(func) : def wrapper() : print "#tomatoes#" func() print "~salad~" return wrapper def sandwich(food="--ham--") : print food sandwich() #輸出 : --ham-- sandwich = bread(ingredients(sandwich)) sandwich() #輸出: #</''' '''\> #tomatoes# # --ham-- # ~salad~ #<\______/>
加上語法糖,代碼可以更簡潔:
def bread(func) : def wrapper() : print "</''' '''\>" func() print "<\______/>" return wrapper def ingredients(func) : def wrapper() : print "#tomatoes#" func() print "~salad~" return wrapper @bread @ingredients def sandwich(food="--ham--") : print food sandwich()
看完了這篇文章,相信你對python的修飾器是什么有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。