php對(duì)閉包的定義是匿名函數(shù),我之前對(duì)python閉包的理解是:外部函數(shù)以內(nèi)部函數(shù)作為返回值革半,稱之為閉包1ā!S止佟(錯(cuò)的延刘,1、不是以內(nèi)部函數(shù)作為返回值赏胚,是返回內(nèi)部函數(shù)的引用访娶;2、閉包是對(duì)變量作用域的應(yīng)用)
最近在重新看Python一些基礎(chǔ)的東西觉阅,突然發(fā)現(xiàn)之前自己對(duì)python閉包的概念理解是特么錯(cuò)的崖疤!
在解釋閉包之前,先說一個(gè)定義:Python中如果在一個(gè)函數(shù)的內(nèi)部定義了另一個(gè)函數(shù)典勇,外部的我們叫他外函數(shù)劫哼,內(nèi)部的我們叫他內(nèi)函數(shù)。
閉包:
在一個(gè)外函數(shù)中定義了一個(gè)內(nèi)函數(shù)割笙,內(nèi)函數(shù)里運(yùn)用了外函數(shù)的臨時(shí)變量权烧,并且外函數(shù)的返回值是內(nèi)函數(shù)的引用。這樣就構(gòu)成了一個(gè)閉包伤溉。(要知道必須要用到外部的函數(shù)臨時(shí)變量才能稱之為閉包般码,閉包是對(duì)變量作用域的應(yīng)用,而不是簡(jiǎn)單地返回一個(gè)函數(shù))
有點(diǎn)青澀難懂乱顾,上代碼吧:
# outer是外部函數(shù) a和b都是外函數(shù)的臨時(shí)變量(你也可以稱之為環(huán)境變量)
def outer( a ):
b = 10
# inner是內(nèi)函數(shù)
def inner():
#在內(nèi)函數(shù)中 用到了外函數(shù)的臨時(shí)變量
print(a+b)
# 外函數(shù)的返回值是內(nèi)函數(shù)的引用
return inner
if __name__ == '__main__':
# 在這里我們調(diào)用外函數(shù)傳入?yún)?shù)5
#此時(shí)外函數(shù)兩個(gè)臨時(shí)變量 a是5 b是10 板祝,并創(chuàng)建了內(nèi)函數(shù),然后把內(nèi)函數(shù)的引用返回存給了demo
# 外函數(shù)結(jié)束的時(shí)候發(fā)現(xiàn)內(nèi)部函數(shù)將會(huì)用到自己的臨時(shí)變量走净,這兩個(gè)臨時(shí)變量就不會(huì)釋放券时,會(huì)綁定給這個(gè)內(nèi)部函數(shù)
demo = outer(5)
# 我們調(diào)用內(nèi)部函數(shù),看一看內(nèi)部函數(shù)是不是能使用外部函數(shù)的臨時(shí)變量
# demo存了外函數(shù)的返回值伏伯,也就是inner函數(shù)的引用橘洞,這里相當(dāng)于執(zhí)行inner函數(shù)
demo() # 15
demo2 = outer(7)
demo2()#17
如何在閉包的內(nèi)部函數(shù)修改外部函數(shù)的臨時(shí)變量:
1、在python3中说搅,可以用nonlocal 關(guān)鍵字聲明 一個(gè)變量炸枣, 表示這個(gè)變量不是局部變量空間的變量,需要向上一層變量空間找這個(gè)變量。
2抛虏、使用可變類型數(shù)據(jù)博其,比如list和dict!
# outer是外部函數(shù) a和b都是外函數(shù)的臨時(shí)變量
def outer( a ):
b = 10 # a和b都是閉包變量
c = [a] #這里對(duì)應(yīng)修改閉包變量的方法2
# inner是內(nèi)函數(shù)
def inner():
#內(nèi)函數(shù)中想修改閉包變量
# 方法1 nonlocal關(guān)鍵字聲明
nonlocal b
b+=1
# 方法二迂猴,把閉包變量修改成可變數(shù)據(jù)類型 比如列表
c[0] += 1
print(c[0])
print(b)
# 外函數(shù)的返回值是內(nèi)函數(shù)的引用
return inner
if __name__ == '__main__':
demo = outer(5)
demo() # 6 11
還有一點(diǎn)需要注意:
使用閉包的過程中慕淡,一旦外函數(shù)被調(diào)用一次返回了內(nèi)函數(shù)的引用,雖然每次調(diào)用內(nèi)函數(shù)沸毁,是開啟一個(gè)函數(shù)執(zhí)行過后消亡峰髓,但是閉包變量實(shí)際上只有一份,每次開啟內(nèi)函數(shù)都在使用同一份閉包變量
def outer(x):
def inner(y):
nonlocal x
x+=y
return x
return inner
a = outer(10)
print(a(1)) //11
print(a(3)) //14