国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

簡單講解Python中的閉包

2019-11-25 17:05:34
字體:
供稿:網(wǎng)友

閉包并不是什么新奇的概念,它早在高級語言開始發(fā)展的年代就產(chǎn)生了。閉包(Closure)是詞法閉包(Lexical Closure)的簡稱。對閉包的具體定義有很多種說法,這些說法大體可以分為兩類:
一種說法認(rèn)為閉包是符合一定條件的函數(shù),比如參考資源中這樣定義閉包:閉包是在其詞法上下文中引用了自由變量的函數(shù)。
另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。比如參考資源中就有這樣的的定義:在實現(xiàn)深約束時,需要創(chuàng)建一個能顯式表示引用環(huán)境的東西,并將它與相關(guān)的子程序捆綁在一起,這樣捆綁起來的整體被稱為閉包。

就像這樣:

#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是個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

簡單說,閉包就是根據(jù)不同的配置信息得到不同的結(jié)果

python實例
看概念總是讓人摸不著頭腦,看幾個python小例子就會了

例1

def make_adder(addend):  def adder(augend):    return augend + addend  return adderp = make_adder(23)q = make_adder(44)print p(100)print q(100)

運行結(jié)果:

123144

分析一下:
我們發(fā)現(xiàn),make_adder是一個函數(shù),包括一個參數(shù)addend,比較特殊的地方是這個函數(shù)里面又定義了一個新函數(shù),這個新函數(shù)里面的一個變量正好是外部make_adder的參數(shù).也就是說,外部傳遞過來的addend參數(shù)已經(jīng)和adder函數(shù)綁定到一起了,形成了一個新函數(shù),我們可以把addend看做新函數(shù)的一個配置信息,配置信息不同,函數(shù)的功能就不一樣了,也就是能得到定制之后的函數(shù).

再看看運行結(jié)果,我們發(fā)現(xiàn),雖然p和q都是make_adder生成的,但是因為配置參數(shù)不同,后面再執(zhí)行相同參數(shù)的函數(shù)后得到了不同的結(jié)果.這就是閉包.

例2

def hellocounter (name):  count=[0]   def counter():    count[0]+=1    print 'Hello,',name,',',str(count[0])+' access!'  return counterhello = hellocounter('ma6174')hello()hello()hello() 

執(zhí)行結(jié)果

Hello, ysisl , 1 access!Hello, ysisl , 2 access!Hello, ysisl , 3 access!

分析一下
這個程序比較有趣,我們可以把這個程序看做統(tǒng)計一個函數(shù)調(diào)用次數(shù)的函數(shù).count[0]可以看做一個計數(shù)器,沒執(zhí)行一次hello函數(shù),count[0]的值就加1。也許你會有疑問:為什么不直接寫count而用一個列表?這是python2的一個bug,如果不用列表的話,會報這樣一個錯誤:

UnboundLocalError: local variable 'count' referenced before assignment.

什么意思?就是說conut這個變量你沒有定義就直接引用了,我不知道這是個什么東西,程序就崩潰了.于是,再python3里面,引入了一個關(guān)鍵字:nonlocal,這個關(guān)鍵字是干什么的?就是告訴python程序,我的這個count變量是再外部定義的,你去外面找吧.然后python就去外層函數(shù)找,然后就找到了count=0這個定義和賦值,程序就能正常執(zhí)行了.

python3 代碼

def hellocounter (name):  count=0   def counter():    nonlocal count    count+=1    print 'Hello,',name,',',str(count[0])+' access!'  return counterhello = hellocounter('ma6174')hello()hello()hello() 

例3

def makebold(fn):  def wrapped():    return "<b>" + fn() + "</b>"  return wrappeddef makeitalic(fn):  def wrapped():    return "<i>" + fn() + "</i>"  return wrapped@makebold@makeitalicdef hello():  return "hello world"print hello() 

執(zhí)行結(jié)果

<b><i>hello world</i></b>

簡單分析
怎么樣?這個程序熟悉嗎?這不是傳說的的裝飾器嗎?對,這就是裝飾器,其實,裝飾器就是一種閉包,我們再回想一下裝飾器的概念:對函數(shù)(參數(shù),返回值等)進(jìn)行加工處理,生成一個功能增強版的一個函數(shù)。再看看閉包的概念,這個增強版的函數(shù)不就是我們配置之后的函數(shù)嗎?區(qū)別在于,裝飾器的參數(shù)是一個函數(shù)或類,專門對類或函數(shù)進(jìn)行加工處理。

python里面的好多高級功能,比如裝飾器,生成器,列表推到,閉包,匿名函數(shù)等,開發(fā)中用一下,可能會達(dá)到事半功倍的效果!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 沾益县| 图木舒克市| 沾益县| 武胜县| 襄汾县| 溧阳市| 吉林省| 忻城县| 瑞金市| 宁德市| 临城县| 阳曲县| 南安市| 乌兰浩特市| 铅山县| 韶山市| 东至县| 莆田市| 丹江口市| 靖州| 扎赉特旗| 云安县| 曲麻莱县| 正定县| 德令哈市| 九江市| 永年县| 罗江县| 遂平县| 三亚市| 永安市| 瑞昌市| 龙江县| 深水埗区| 个旧市| 教育| 侯马市| 南宁市| 临颍县| 玛纳斯县| 镇巴县|