簡(jiǎn)單講解Python中的閉包
閉包并不是什么新奇的概念,它早在高級(jí)語(yǔ)言開(kāi)始發(fā)展的年代就產(chǎn)生了。閉包(Closure)是詞法閉包(Lexical Closure)的簡(jiǎn)稱。對(duì)閉包的具體定義有很多種說(shuō)法,這些說(shuō)法大體可以分為兩類:
一種說(shuō)法認(rèn)為閉包是符合一定條件的函數(shù),比如參考資源中這樣定義閉包:閉包是在其詞法上下文中引用了自由變量的函數(shù)。
另一種說(shuō)法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。比如參考資源中就有這樣的的定義:在實(shí)現(xiàn)深約束時(shí),需要?jiǎng)?chuàng)建一個(gè)能顯式表示引用環(huán)境的東西,并將它與相關(guān)的子程序捆綁在一起,這樣捆綁起來(lái)的整體被稱為閉包。
就像這樣:
#python 中的閉包 ... def func(data): ... count = [data] ... def wrap(): ... count[0] += 1 ... return count[0] ... return wrap ... ... a = func(1) >>> a() 5: 2 >>> a() 6: 3 def func(x): ... return lambda y :y+x >>> b = func(1) >>> b(1) 7: 2 >>> b(2) 8: 3 >>> print b #這里b是個(gè)function 在ruby中是proc <function <lambda> at 0x01AC68F0> def addx(x): ... def adder (y): return x + y ... return adder >>> add8 = addx(8) >>> add8(8) 9: 16
簡(jiǎn)單說(shuō),閉包就是根據(jù)不同的配置信息得到不同的結(jié)果
python實(shí)例
看概念總是讓人摸不著頭腦,看幾個(gè)python小例子就會(huì)了
例1
def make_adder(addend):
def adder(augend):
return augend + addend
return adder
p = make_adder(23)
q = make_adder(44)
print p(100)
print q(100)
運(yùn)行結(jié)果:
123 144
分析一下:
我們發(fā)現(xiàn),make_adder是一個(gè)函數(shù),包括一個(gè)參數(shù)addend,比較特殊的地方是這個(gè)函數(shù)里面又定義了一個(gè)新函數(shù),這個(gè)新函數(shù)里面的一個(gè)變量正好是外部make_adder的參數(shù).也就是說(shuō),外部傳遞過(guò)來(lái)的addend參數(shù)已經(jīng)和adder函數(shù)綁定到一起了,形成了一個(gè)新函數(shù),我們可以把a(bǔ)ddend看做新函數(shù)的一個(gè)配置信息,配置信息不同,函數(shù)的功能就不一樣了,也就是能得到定制之后的函數(shù).
再看看運(yùn)行結(jié)果,我們發(fā)現(xiàn),雖然p和q都是make_adder生成的,但是因?yàn)榕渲脜?shù)不同,后面再執(zhí)行相同參數(shù)的函數(shù)后得到了不同的結(jié)果.這就是閉包.
例2
def hellocounter (name):
count=[0]
def counter():
count[0]+=1
print 'Hello,',name,',',str(count[0])+' access!'
return counter
hello = hellocounter('ma6174')
hello()
hello()
hello()
執(zhí)行結(jié)果
Hello, ysisl , 1 access! Hello, ysisl , 2 access! Hello, ysisl , 3 access!
分析一下
這個(gè)程序比較有趣,我們可以把這個(gè)程序看做統(tǒng)計(jì)一個(gè)函數(shù)調(diào)用次數(shù)的函數(shù).count[0]可以看做一個(gè)計(jì)數(shù)器,沒(méi)執(zhí)行一次hello函數(shù),count[0]的值就加1。也許你會(huì)有疑問(wèn):為什么不直接寫count而用一個(gè)列表?這是python2的一個(gè)bug,如果不用列表的話,會(huì)報(bào)這樣一個(gè)錯(cuò)誤:
UnboundLocalError: local variable 'count' referenced before assignment.
什么意思?就是說(shuō)conut這個(gè)變量你沒(méi)有定義就直接引用了,我不知道這是個(gè)什么東西,程序就崩潰了.于是,再python3里面,引入了一個(gè)關(guān)鍵字:nonlocal,這個(gè)關(guān)鍵字是干什么的?就是告訴python程序,我的這個(gè)count變量是再外部定義的,你去外面找吧.然后python就去外層函數(shù)找,然后就找到了count=0這個(gè)定義和賦值,程序就能正常執(zhí)行了.
python3 代碼
def hellocounter (name):
count=0
def counter():
nonlocal count
count+=1
print 'Hello,',name,',',str(count[0])+' access!'
return counter
hello = hellocounter('ma6174')
hello()
hello()
hello()
例3
def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
@makebold
@makeitalic
def hello():
return "hello world"
print hello()
執(zhí)行結(jié)果
<b><i>hello world</i></b>
簡(jiǎn)單分析
怎么樣?這個(gè)程序熟悉嗎?這不是傳說(shuō)的的裝飾器嗎?對(duì),這就是裝飾器,其實(shí),裝飾器就是一種閉包,我們?cè)倩叵胍幌卵b飾器的概念:對(duì)函數(shù)(參數(shù),返回值等)進(jìn)行加工處理,生成一個(gè)功能增強(qiáng)版的一個(gè)函數(shù)。再看看閉包的概念,這個(gè)增強(qiáng)版的函數(shù)不就是我們配置之后的函數(shù)嗎?區(qū)別在于,裝飾器的參數(shù)是一個(gè)函數(shù)或類,專門對(duì)類或函數(shù)進(jìn)行加工處理。
python里面的好多高級(jí)功能,比如裝飾器,生成器,列表推到,閉包,匿名函數(shù)等,開(kāi)發(fā)中用一下,可能會(huì)達(dá)到事半功倍的效果!
- Python中的閉包總結(jié)
- Python中的閉包實(shí)例詳解
- Python中用函數(shù)作為返回值和實(shí)現(xiàn)閉包的教程
- Python函數(shù)中的函數(shù)(閉包)用法實(shí)例
- Python的幾個(gè)高級(jí)語(yǔ)法概念淺析(lambda表達(dá)式閉包裝飾器)
- Python中的閉包詳細(xì)介紹和實(shí)例
- 簡(jiǎn)析Python的閉包和裝飾器
- python中函數(shù)總結(jié)之裝飾器閉包詳解
- Python閉包的兩個(gè)注意事項(xiàng)(推薦)
- Python閉包執(zhí)行時(shí)值的傳遞方式實(shí)例分析
相關(guān)文章
跟老齊學(xué)Python之使用Python操作數(shù)據(jù)庫(kù)(1)
本文詳細(xì)講述了使用python操作數(shù)據(jù)庫(kù)所需要了解的知識(shí)以及準(zhǔn)備工作,十分的詳盡,這里推薦給想學(xué)習(xí)python的小伙伴。2014-11-11
python實(shí)現(xiàn)獲取電腦所連接的wifi密碼
電腦連接wifi后,很難直觀地看到當(dāng)前連接wifi的密碼,需要借助命令行公管局才可以查看到相關(guān)信息,本文為大家介紹一下如何利用python獲取電腦所連接的wifi密碼,感興趣的可以了解下2023-11-11
python目標(biāo)檢測(cè)實(shí)現(xiàn)黑花屏分類任務(wù)示例
這篇文章主要為大家介紹了python目標(biāo)檢測(cè)實(shí)現(xiàn)黑花屏分類任務(wù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
python中向二維數(shù)組中添加整行或者增列元素問(wèn)題
這篇文章主要介紹了python中向二維數(shù)組中添加整行或者增列元素問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
Python?pygame項(xiàng)目實(shí)戰(zhàn)監(jiān)聽(tīng)退出事件
這篇文章主要介紹了Python?pygame項(xiàng)目實(shí)戰(zhàn)監(jiān)聽(tīng)退出事件,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08

