淺談python裝飾器探究與參數(shù)的領(lǐng)取
首先上原文:
現(xiàn)在,假設(shè)我們要增強(qiáng)now()函數(shù)的功能,比如,在函數(shù)調(diào)用前后自動(dòng)打印日志,但又不希望修改now()函數(shù)的定義,這種在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式,稱之為“裝飾器”(Decorator)。
本質(zhì)上,decorator就是一個(gè)返回函數(shù)的高階函數(shù)。
Decorator本質(zhì)是高階函數(shù)?
不信邪的我試了下..
def g(): print("這里是G") return "G" @g def f(): print("這里是F") return 1 ''' -------------------------------------------- line 5, in <module> @g TypeError: g() takes 0 positional arguments but 1 was given >>> '''
運(yùn)行結(jié)果在注釋里
尷尬了...g被強(qiáng)制塞了個(gè)參數(shù),那個(gè)參數(shù)應(yīng)該是g"修飾的對(duì)象"
修改下繼續(xù).....
def g(f): print("這里是G") return "G" @g def f(): print("這里是F") return 1 ''' -------------------------------------------- 這里是G >>> f() Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> f() TypeError: 'str' object is not callable '''
str對(duì)象不能被調(diào)用,,,這里的str只有一個(gè),就是g的返回值
為了驗(yàn)證下,我把"G"改成了2
結(jié)果是
TypeError: 'int' object is not callable
OK了,大概意思就是,裝飾器首先被"塞"一個(gè)參數(shù),然后,返回值還要被調(diào)用一次,然而好像只有函數(shù)才能被調(diào)用,,所以,為了不報(bào)錯(cuò),裝飾器必須返回一個(gè)函數(shù),裝飾器必須是高階函數(shù)......
我表示不服( ̄へ ̄),不就是函數(shù)嗎,g的參數(shù)就是函數(shù),,,騷操作上腦ing
def g(f): print("這里是G") return f @g def f(): print("這里是F") return 1 ''' -------------------------------------------- 這里是G >>> f() 這里是F '1' '''
運(yùn)行成功.但是....說(shuō)好的"打印日志功能"呢,#沒(méi)錯(cuò)"這里是G"就是我想要的日志
疑點(diǎn)一: 打印的"這里是G"是第一行,是在輸入"f()"之前發(fā)生的....
疑點(diǎn)二: 輸入"f()"后,"這里是G"沒(méi)打出來(lái).....
#單看g函數(shù),它不算是"高階函數(shù)"
作為成功的例子,它太失敗了┐( ̄ヘ ̄)┌
##好吧,我投降了,負(fù)隅頑抗也不怎么有意思.....
閉包告訴我們一個(gè)道理,,,為了保證返回值一定是函數(shù),最好的措施就是"在函數(shù)內(nèi)部,現(xiàn)場(chǎng)造一個(gè)函數(shù)然后扔出去"
def g(f): print("這里是G") def h(): print('這里是H') return "H" return h @g def f(): print("這里是F") return 1 ''' -------------------------------------------- 這里是G >>> f() 這里是H 'H' >>> f() 這里是H 'H' >>> '''
f函數(shù)不執(zhí)行了,,是的沒(méi)錯(cuò),我還多試了一次的
另外,兩條日志只有里面的能用......(下文會(huì)解釋的)
看了一下書,h函數(shù)返回f()的話,f函數(shù)就能被執(zhí)行了,,,,,個(gè)人感覺(jué)裝飾器應(yīng)該叫"劫持器"
def g(f): print("這里是G") def h(): print('這里是H') return f() return h @g def f(): print("這里是F") return 1 ''' -------------------------------------------- 這里是G >>> f() 這里是H 這里是F '1' >>> f <function g.<locals>.h at 0x0000020CBDBB6C80> '''
按書上的思路解釋下
''' @g def f(): pass >>>f() 等價(jià)于 >>>g(f) () g函數(shù)執(zhí)行,返回 >>>h () h函數(shù)執(zhí)行(打印日志) >>>f() f執(zhí)行,返回1 >>>1 '''
加上參數(shù),
def g(f): print("這里是G") def h(*args,**kw): print('這里是H') return f(*args,**kw) return h @g def f(*args,**kw): print("這里是F") return "1" ''' >>>f(*args,**kw) 等價(jià)于 >>>g(f) (*args,**kw) g函數(shù)執(zhí)行,返回 >>>h (*args,**kw) h函數(shù)執(zhí)行(打印日志) >>>f(*args,**kw) f執(zhí)行,返回1 >>>1 '''
可以看出,(*args,**kw)本改被h函數(shù)拿走,所以,觀察h函數(shù),h把它的參數(shù)原封不動(dòng)的交給了f
機(jī)智的我動(dòng)了歪主意
def g(f): print("這里是G") def h():#h沒(méi)要求參數(shù) print('這里是H') return f return h @g def f(*args,**kw): print("這里是F") return "1" ''' >>>f()(*args,**kw) 等價(jià)于 >>>g(f) ()(*args,**kw) g函數(shù)執(zhí)行,返回 >>>h ()(*args,**kw) h函數(shù)執(zhí)行,h拿的空參數(shù) (打印日志) >>>f(*args,**kw) f執(zhí)行,返回1 >>>1 '''
可是新的問(wèn)題來(lái)了,后面f調(diào)用的時(shí)候得多加個(gè)空括號(hào),否則
''' >>>f(*args,**kw) 等價(jià)于 >>>g(f) (*args,**kw) g函數(shù)執(zhí)行,返回 >>>h (*args,**kw) h函數(shù)執(zhí)行(打印日志)返回f >>>f 這是一個(gè)函數(shù)對(duì)象 '''
以上告訴我們一個(gè)道理"函數(shù)執(zhí)行不執(zhí)行取決于后面有沒(méi)有括號(hào)"
舉個(gè)例子
def m(a): print(a) return m print(m(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)) ''' ----------------------------- 2 4 6 8 10 <function m at 0x000002832BDB10D0>
燒腦時(shí)刻
f = a.b.c()()[0]()[d()()[e]]
a模塊的b類的c方法是高階函數(shù),最終返回一個(gè)列表,列表里有個(gè)函數(shù)
函數(shù)又返回一個(gè)字典............
以上這篇淺談python裝飾器探究與參數(shù)的領(lǐng)取就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python?Flask-Login構(gòu)建強(qiáng)大的用戶認(rèn)證系統(tǒng)實(shí)例探究
這篇文章主要為大家介紹了Python?Flask-Login構(gòu)建強(qiáng)大的用戶認(rèn)證系統(tǒng)示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01解決python寫入mysql中datetime類型遇到的問(wèn)題
今天小編就為大家分享一篇解決python寫入mysql中datetime類型遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python設(shè)計(jì)模式之工廠模式簡(jiǎn)單示例
這篇文章主要介紹了Python設(shè)計(jì)模式之工廠模式,簡(jiǎn)單說(shuō)明了工廠模式的原理,并結(jié)合實(shí)例形式給出了Python實(shí)現(xiàn)工廠模式的具體操作技巧,需要的朋友可以參考下2018-01-01scrapy-redis分布式爬蟲(chóng)的搭建過(guò)程(理論篇)
這篇文章主要介紹了scrapy-redis分布式爬蟲(chóng)的搭建過(guò)程(理論篇),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09新手必備Python開(kāi)發(fā)環(huán)境搭建教程
今天向大家介紹如何搭建Python開(kāi)發(fā)環(huán)境, Python可應(yīng)用于多平臺(tái)包括 Linux 和 Mac OS X,文中有非常詳細(xì)的圖文介紹,需要的朋友可以參考下2021-05-05