Python裝飾器知識點(diǎn)補(bǔ)充
首先回顧一下關(guān)于Python裝飾器以及裝飾器模式
補(bǔ)全
根據(jù)Java實(shí)現(xiàn)裝飾器模式的,我們可以寫下面一段代碼:
import logging def use_logging(func): logging.warn("%s is running" % func.__name__) return func def foo(): print('i am foo') foo = use_logging(foo) foo() # 調(diào)用
這個(gè)實(shí)現(xiàn)對于上篇文章中提到的Java使用裝飾器。上面也是一個(gè)裝飾器,實(shí)現(xiàn)最簡單的一個(gè)增加函數(shù)日志的功能,但是如果這個(gè)額外功能是要去檢測傳入的參數(shù)時(shí),這時(shí)上面的就不行了。這時(shí)12步輕松搞定python裝飾器中的例子還是精妙的。
# 裝飾器 def wrapper(func): def checker(a, b): # 1 if a.x < 0 or a.y < 0: a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0) if b.x < 0 or b.y < 0: b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0) ret = func(a, b) if ret.x < 0 or ret.y < 0: ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0) return ret return checker # 原函數(shù) def add(a, b): return Coordinate(a.x + b.x, a.y + b.y) # 使用裝飾 add = wrapper(add)
細(xì)心你會發(fā)現(xiàn),裝飾器函數(shù)的參數(shù)就是傳入的原函數(shù),而內(nèi)部函數(shù)的參數(shù)跟原函數(shù)一模一樣,最外層返回的是內(nèi)部函數(shù)的引用,內(nèi)部函數(shù)返回的是傳入?yún)?shù)的引用調(diào)用的結(jié)果
這里用到了函數(shù)作為參數(shù)特性,當(dāng)然還有些閉包的知識,具體請看 上面提到的博客鏈接,真的講的不錯(cuò)。
而上篇說到的Python裝飾 特性就是這個(gè)神奇的語法糖了,可以這樣使用
# 原函數(shù) @wrapper def add(a, b): return Coordinate(a.x + b.x, a.y + b.y)
帶參數(shù)的裝飾器
如果要實(shí)現(xiàn)一個(gè)帶參數(shù)的裝飾器,那要怎么寫呢
def time_diff(s): def decorator(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print("[%s]執(zhí)行程序所用時(shí)間: %s" % (s, end_time - start_time)) return res return wrapper return decorator @time_diff("polynomial_1") def polynomial_1(n, x): res = 0 for i in range(n): res += i*pow(x, i) return res
調(diào)用并執(zhí)行輸出結(jié)果:
print(polynomial_1(1, 5)) [duoxiangshi_1]執(zhí)行程序所用時(shí)間: 4.76837158203125e-06 0
帶參數(shù)的裝飾器需要在不帶參數(shù)裝飾器外再定義一層函數(shù),最外層函數(shù)的返回值是第二層函數(shù)的引用。
總結(jié):多些多練,用于實(shí)際中,才能更加熟練。最近學(xué)數(shù)據(jù)結(jié)構(gòu)與算法,寫些裝飾器用來看程序執(zhí)行時(shí)間,真是再方便不過了!
相關(guān)文章
使用celery和Django處理異步任務(wù)的流程分析
Celery是 一個(gè)專注于實(shí)時(shí)處理的任務(wù)隊(duì)列,它還支持任務(wù)調(diào)度。 Celery快速,簡單,高度可用且靈活。這篇文章主要介紹了使用celery和Django處理異步任務(wù)的流程分析,需要的朋友可以參考下2020-02-02pycharm中使用anaconda部署python環(huán)境的方法步驟
這篇文章主要介紹了pycharm中使用anaconda部署python環(huán)境的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12matplotlib圖形整合之多個(gè)子圖繪制的實(shí)例代碼
matplotlib繪制多個(gè)子圖的時(shí)候,我們可以根據(jù)自己的想法去排列子圖的順序,也可以生成不同的子圖數(shù)量,本文就詳細(xì)的介紹了matplotlib 多子圖繪制,具有一定的參考價(jià)值,感興趣的可以了解一下2022-04-04