Python裝飾器知識(shí)點(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)對(duì)于上篇文章中提到的Java使用裝飾器。上面也是一個(gè)裝飾器,實(shí)現(xiàn)最簡(jiǎn)單的一個(gè)增加函數(shù)日志的功能,但是如果這個(gè)額外功能是要去檢測(cè)傳入的參數(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ì)心你會(huì)發(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)然還有些閉包的知識(shí),具體請(qǐ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)文章
Python操作Redis數(shù)據(jù)庫(kù)的詳細(xì)教程與應(yīng)用實(shí)戰(zhàn)
Redis是一個(gè)高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),支持多種類型的數(shù)據(jù)結(jié)構(gòu),如字符串、哈希表、列表、集合和有序集合等,在Python中,通過redis-py庫(kù)可以方便地操作Redis數(shù)據(jù)庫(kù),本文將詳細(xì)介紹如何在Python代碼中操作Redis,需要的朋友可以參考下2024-08-08
python實(shí)現(xiàn)AES和RSA加解密的方法
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)AES和RSA加解密的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
Python pygame實(shí)現(xiàn)圖像基本變換的示例詳解
pygame的transform中封裝了一些基礎(chǔ)的圖像處理函數(shù),這篇文章主要為大家介紹了pygame實(shí)現(xiàn)圖像的基本變換,例如縮放、旋轉(zhuǎn)、鏡像等,感興趣的小伙伴可以了解一下2023-11-11
詳解如何使用Python實(shí)現(xiàn)刪除重復(fù)文件
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)刪除重復(fù)文件功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-10-10
python3+PyQt5實(shí)現(xiàn)文檔打印功能
這篇文章主要為大家詳細(xì)介紹了python3+PyQt5實(shí)現(xiàn)文檔打印功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
解決pycharm上的jupyter notebook端口被占用問題
今天小編就為大家分享一篇解決pycharm上的jupyter notebook端口被占用問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12

