[Python教學] 裝飾詞原理到應用 - MAX行銷誌

文章推薦指數: 80 %
投票人數:10人

Python 裝飾詞(Decorator) 被大量廣泛的使用在各方library,是非常實用和必須了解的基. 跳至主要內容 Python裝飾詞(Decorator)被大量廣泛的使用在各方library,是非常實用和必須了解的基礎,本篇介紹了從原理到應用,建議讀者可以跟著敲一次code,會對裝飾詞有更深入的了解唷~ ▍為什麼需要裝飾詞: 降低程式碼重複率易讀性高靈活度高 文章目錄 一.裝飾詞的原理二.語法糖(SyntaxCandy)三.裝飾詞的副作用:函式名稱四.觸發先後順序五.帶參數(*args,**kargs)六.用Class寫裝飾詞 一.裝飾詞的原理 ▍首先了解:變數名與函式物件(object) 我們先定義了一個函式為foo,我們print(foo),會得到functionfooat0x1028831e0表示foo是一個變數名,並且指向一個函式物件(object)。

如果要調用函式的話,則加上(),foo(),即可調用函式。

deffoo(): return‘bar’ print(foo) print(foo()) >>> >>>bar ▍開始解說裝飾詞: 首先我們在deftimer(func):將func變數名稱傳入,接下來定義defwrap(sleep_time)函式,並且在裡面將剛剛傳入的func(sleep_time)調用,這樣就完成一個簡單的裝飾詞囉! importtime deftimer(func): defwrap(sleep_time): t_start=time.time() func(sleep_time) t_end=time.time() t_count=t_end-t_start print('[花費時間]',t_count) returnwrap defdosomething(sleep_time): print('dosomething') time.sleep(sleep_time) foo=timer(dosomething) foo(3) >>>dosomething >>>[花費時間]3.004279136657715 二.語法糖(SyntaxCandy) 如果不想寫成foo=timer(dosomething),只需要加上@timer,並直接調用dosomething()函式執行 deftimer(func): defwrap(sleep_time): t_start=time.time() func(sleep_time) t_end=time.time() t_count=t_end-t_start print(‘[花費時間]’,t_count) returnwrap @timer defdosomething(sleep_time): print(‘dosomething’) time.sleep(sleep_time) dosomething(3) >>>dosomething >>>[花費時間]3.003619909286499 三.裝飾詞的副作用:函式名稱 裝飾詞在被wrap包一層後,其__name__屬性就會被修改成wrap deftimer(func): defwrap(): t_start=time.time() func() t_end=time.time() t_count=t_end-t_start print(‘[花費時間]’,t_count) returnwrap @timer defdosomething(): print('dosomething') dosomething() print(dosomething.__name__) >>>wrap 如果要消除這個副作用的話,可以使用python內建的functools,只需要在defwrap()之前,加上@wraps(func),即可獲得原先的__name__屬性dosomething。

fromfunctoolsimportwraps deftimer(func): @wraps(func) defwrap(): t_start=time.time() func() t_end=time.time() t_count=t_end-t_start print(‘[花費時間]’,t_count) returnwrap @timer defdosomething(): print('dosomething') dosomething() print(dosomething.__name__) >>>dosomething 四.觸發先後順序 如果有兩個Decorator裝飾詞要使用的話怎麼辦,其實只需要加在上面一行即可,順序的話會從上而下觸發 deftimer(func): @wraps(func) defwrap(): t_start=time.time() func() t_end=time.time() t_count=t_end-t_start print(‘[花費時間]’,t_count) returnwrap deffunc_print_one(func): @wraps(func) defwrap(): print(‘thisisfunc_print_one’) func() returnwrap deffunc_print_two(func): @wraps(func) defwrap(): print('thisisfunc_print_two') func() returnwrap @timer @func_print_one @func_print_two defdosomething(): print('dosomething') dosomething() >>>thisisfunc_print_one >>>thisisfunc_print_two >>>dosomething >>>[花費時間]2.3126602172851562e-05 五.帶參數(*args,**kargs) 只需在defwrap()和func()中加入*args,**kargs即可調用參數,範例如下: deftimer(func): @wraps(func) defwrap(*args,**kargs): t_start=time.time() value=func(*args,**kargs) t_end=time.time() t_count=t_end-t_start print('[花費時間]',t_count) returnvalue returnwrap deffunc_print(func): @wraps(func) defwrap(*args,**kargs): print('thisisfunc_print') value=func(*args,**kargs) returnvalue returnwrap @timer @func_print defdosomething(a,b): print('dosomething') print(a+b) dosomething(1,2) >>>thisisfunc_print >>>dosomething >>>3 >>>[花費時間]1.52587890625e-05 六.用Class寫裝飾詞 如果是Class的方法來寫裝飾詞的話,會將wrap寫在__call__裡面來調用,範例如下: classTimer: def__init__(self,time_sleep): print('[__init__]') print('[time_sleep]:',time_sleep) self.time_sleep=time_sleep def__call__(self,func): @wraps(func) defwrap(*args,**kargs): t_start=time.time() time.sleep(self.time_sleep) value=func(*args,**kargs) t_end=time.time() t_count=t_end-t_start print('[共花費時間]',t_count) returnvalue returnwrap @Timer(time_sleep=3) defdosomethingClass(a,b): print('dosomething') print('a+b=',a+b) dosomethingClass(1,2) >>>[__init__] >>>[time_sleep]:3 >>>dosomething >>>a+b=3 >>>[共花費時間]3.0002880096435547 本篇簡單的介紹了裝飾詞的原理、語法糖的使用、函式名稱的副作用、觸發的先後順序、帶參數和如何使用Class來寫裝飾詞,建議可以實際將code打一次,會對裝飾詞有更深的了解唷~ 關於Python物件導向教學的延伸閱讀: ▍本站的其他相關教學: [Python教學]一切皆為物件,到底什麼是物件Object?[Python教學]物件導向–Class類的封裝/繼承/多型[Python教學]Class/Static/AbstractMethod初探[Python教學]@property是什麼?使用場景和用法介紹[Python教學]裝飾詞原理到應用 那麼[Python教學]裝飾詞原理到應用結束囉,感謝收看! 有關Max行銷誌的最新文章,都會發佈在Max行銷誌的Facebook粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷! 文章導覽 [Flask教學]Flask-SQLAlchemy-ORM一對多關聯篇(三)[Python教學]Class/Static/AbstractMethod初探 發佈留言取消回覆發佈留言必須填寫的電子郵件地址不會公開。

必填欄位標示為*留言顯示名稱* 電子郵件地址* 個人網站網址 在瀏覽器中儲存顯示名稱、電子郵件地址及個人網站網址,以供下次發佈留言時使用。

Δ 搜尋關鍵字: Category 01Python數據分析(19) 02Python基礎教學(19) 03Python爬蟲教學(15) 04PythonFlask教學(36) 05PythonDjango教學(3) 06Python資料庫教學(9) 07Python機器學習(3) 08GoogleTagManager教學(9) 09Swift教學(5) 10DataStudio教學(8) 11所有文章(133) LatestPost [零基礎上手]Discord自動參加抽獎機器人(雲端穩定版) HowtouseTornadotransferCrypto? HowtotradeCrypto/NFTSwithSudoswap? [Chrome套件]ETHGASFee和釣魚網站檢測 [零基礎上手]Discord自動發言機器人 List 2022年2月 (1) 2022年1月 (2) 2021年12月 (2) 2021年11月 (1) 2021年10月 (1) 2021年9月 (1) 2021年8月 (1) 2021年7月 (1) 2021年6月 (1) 2021年5月 (1) 2021年4月 (1) 2021年3月 (3) 2021年2月 (1) 2021年1月 (3) 2020年12月 (2) 2020年11月 (2) 2020年10月 (3) 2020年9月 (1) 2020年8月 (5) 2020年7月 (3) 2020年6月 (5) 2020年5月 (11) 2020年4月 (6) 2020年3月 (6) 2020年2月 (1) 2020年1月 (3) 2019年12月 (5) 2019年11月 (5) 2019年10月 (1) 2019年9月 (4) 2019年8月 (2) 2019年7月 (2) 2019年6月 (3) 2019年5月 (1) 2019年4月 (6) 2019年3月 (3) 2019年2月 (1) 2019年1月 (2) 2018年12月 (1) 2018年11月 (10) 2018年10月 (5) 2018年9月 (6) 2018年8月 (1) 2018年7月 (1) 2018年6月 (2) 2018年5月 (2) 2018年4月 (1) 2018年2月 (1) 2018年1月 (1) Comment「LJJ」於〈【數據分析】蝦皮賣家競品分析〉發佈留言「LJJ」於〈【數據分析】蝦皮賣家競品分析〉發佈留言「Max」於〈【數據分析】蝦皮賣家競品分析〉發佈留言「LJJ」於〈【數據分析】蝦皮賣家競品分析〉發佈留言「jeff.lee」於〈【數據分析】蝦皮賣家競品分析〉發佈留言 About Explore



請為這篇文章評分?