您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Python函數裝飾器的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
函數裝飾器是一個可調用對象,它的參數是另外一個函數。比如:
@decorate def target(): print("running target()")
跟下面代碼效果是一樣的:
def target(): print("running target()") target = decorate(target)
簡單實現@decorate:
def decorate(func): def inner(): print("running inner()") return inner
測試一下:
>>> target() running inner() >>> target <function decorate.<locals>.inner at 0x04899D18>
新的target是decorate(target)返回的inner函數。
因為裝飾器只是代碼優化的一種手段,不像if語句for語句那樣,決定了程序流程,所以嚴格來說,裝飾器只是語法糖。它有兩個特性,一是能把被裝飾的函數替換成其他函數,二是裝飾器在加載模塊時立即執行。
若想真正理解裝飾器,需要區分導入時和運行時。函數裝飾器在導入模塊時立即執行,而被裝飾的函數只在明確調用時運行。
接下來通過示例對這個特性進行說明,新建registration.py模塊:
registry = [] def register(func): # 裝飾器函數也可以不定義內部函數 print("running register(%s)" % func) registry.append(func) return func @register def f1(): print("running f1()") @register def f2(): print("running f2()") def f3(): print("running f3()") def main(): print("running main()") print("registry ->", registry) f1() f2() f3() if __name__ == "__main__": main()
從結果能看出來:
@register作用到f1和f2上,在導入時,在main()調用前就執行了。
f3沒有裝飾器,就沒有在main()調用前執行@register。
在main()調用后,明確調用f1()、f2()、f3()才執行函數。
import模塊能看得更明顯:
>>> import registration running register(<function f1 at 0x0189A730>) running register(<function f2 at 0x0189A6E8>)
裝飾器在導入時就執行了。
在《Python設計模式知多少》文章中提到了裝飾器可以更優雅的實現策略模式的最佳策略,它的實現代碼如下:
promos = [] def promotion(promo_func): promos.append(promo_func) return promo_func @promotion def fidelity(order): """5% discount for customers with 1000 or more fidelity points""" return order.total() * .05 if order.customer.fidelity >= 1000 else 0 @promotion def bulk_item(order): """10% discount for each LineItem with 20 or more units""" discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total() * .1 return discount @promotion def large_order(order): """7% discount for orders with 10 or more distinct items""" distinct_items = {item.product for item in order.cart} if len(distinct_items) >= 10: return order.total() * .07 return 0 def best_promo(order): """Select best discount available """ return max(promo(order) for promo in promos)
它解決了"如果想要添加新的促銷策略,那么要定義相應函數并添加到promos列表中"這個缺陷,并有更多優點:
新的促銷策略,用@promotion裝飾器即可添加。
促銷策略函數不用以_promo結尾,可以任意命令。
促銷策略可以在任意模塊定義,只需要使用@promotion裝飾器即可。
感謝各位的閱讀!關于“Python函數裝飾器的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。