摘要:恩如期來啦閉包一函數(shù)作為返回值介紹閉包之前,先了解一下函數(shù)作為返回值的情況。例如之前介紹的裝飾器中,就出現(xiàn)了將函數(shù)作為返回值。當(dāng)執(zhí)行時(shí),相當(dāng)于執(zhí)行,且包含。允許使用關(guān)鍵字創(chuàng)造匿名函數(shù)。例如調(diào)用默認(rèn)可以把匿名函數(shù)作為返回值返回,例如
恩~ 如期來啦“閉包”~
介紹“閉包”之前,先了解一下函數(shù)作為返回值的情況。
高階函數(shù)除了可以接收函數(shù)作為參數(shù)外,還可以把函數(shù)作為結(jié)果值返回。例如之前介紹的裝飾器中,就出現(xiàn)了將函數(shù)作為返回值。
什么是閉包?
當(dāng)在函數(shù)中嵌套另一個(gè)函數(shù)時(shí),如果內(nèi)部函數(shù)引用了外部函數(shù)的變量,則可能產(chǎn)生閉包。
所以閉包產(chǎn)生的三個(gè)條件(缺一不可):
1、必須嵌套一個(gè)內(nèi)部函數(shù)
2、內(nèi)部函數(shù)必須引用外部函數(shù)的變量
3、外部函數(shù)必須返回內(nèi)部函數(shù)
那為什么要試用閉包,閉包的作用呢?
1、閉包可以根據(jù)外部函數(shù)的局部變量來得到不同的結(jié)果
2、當(dāng)閉包執(zhí)行完成后,仍可以保持當(dāng)前的運(yùn)行環(huán)境,執(zhí)行結(jié)果依賴于該函數(shù)上一次的運(yùn)行結(jié)果
2、閉包舉例栗子一:求序列之和
>>> def calc_sum(*args): ... ax = 0 ... for n in args: ... ax = ax + n ... return ax # 返回變量 ... >>> calc_sum(1,2,3) 6
但是,現(xiàn)在如果要求不需要立即取得求和結(jié)果,而是在后面的代碼中,根據(jù)需要再計(jì)算,該怎么弄呢?
我們可以不返回求和的結(jié)果,而返回求和的函數(shù),如下:
>>>def lazy_sum(*args): ... def sum(): # sum()是內(nèi)部函數(shù),可以利用外部函數(shù)的參數(shù) ... ax = 0 ... for n in args: # sum()中使用外部函數(shù)的局部變量 ... ax = ax + n ... return ax ... return sum # 形成閉包,此時(shí),*args保存在返回的函數(shù)中 ... >>>f = lazy_sum(1,3,5,7,9) >>>f # 此時(shí)返回的是求和函數(shù) >>> f() # 調(diào)用函數(shù)f()時(shí),才真正計(jì)算求和的結(jié)果 25
注意:
lazy_sum()函數(shù)的內(nèi)部執(zhí)行順序,執(zhí)行f時(shí),運(yùn)行到return sum處,*args保存在返回函數(shù)中,返回的是sum()函數(shù)。當(dāng)執(zhí)行f()時(shí),相當(dāng)于執(zhí)行sum(),且包含*args。
當(dāng)我們調(diào)用lazy_sun()時(shí),每次都會(huì)返回一個(gè)新的函數(shù),即使傳入相同的參數(shù),但是f()調(diào)用結(jié)果不影響。
我們來驗(yàn)證第二點(diǎn):
# 但是調(diào)用 f1() 與f2()的調(diào)用結(jié)果互不影響 >>> f1 = lazy_sum(1,3,5,7,9) >>> f2 = lazy_sum(1,3,5,7,9) >>> f1.sum at 0x013DD618> >>> f2 .sum at 0x02F92DF8> >>> f1 == f2 False >>> f1() == f2() True >>> f1() 25 >>> f2() 25 >>> id(f1()) 1627215984 >>> id(f2()) 1627215984
說明:f1與f2返回函數(shù)的位置不一樣,所以f1==f2返回結(jié)果為False。
但是不影響最后的執(zhí)行結(jié)果,f1()與f2()的執(zhí)行結(jié)果均為25,且用id()進(jìn)行查看,指向是同一塊區(qū)域。
栗子二:
def count(): fs = [] for i in range(1, 4): def f(): # 返回函數(shù)f()放在循環(huán)里 return i*i fs.append(f) return fs f1, f2, f3 = count()
實(shí)際執(zhí)行結(jié)果為:f1=9 f2=9 f3=9
可能與實(shí)際想的([1,4,9])有點(diǎn)不一樣。因?yàn)?b>f()函數(shù)放在了for循環(huán)里,只有當(dāng)循環(huán)結(jié)束后,最后才返回i=3的執(zhí)行結(jié)果9。
所以返回函數(shù)最好不要引用任何循環(huán)變量,或者說后續(xù)可能變化的量。那如何來修改呢?
def count(): def f(j): def g(): return j*j # 形成閉包 return g fs = [] for i in range(1, 4): fs.append(f(i)) # 一個(gè)i值進(jìn)入后,f(i)立刻被執(zhí)行,并加入到fs中 return fs f1, f2, f3 = count() # 返回函數(shù)g沒有引用j
最后結(jié)果:[1,4,9] 即f1=1 f2=4 f3=9
定義:匿名函數(shù)指一類無需定義標(biāo)識(shí)符函數(shù)名的函數(shù)或者子程序。Python允許使用lambda關(guān)鍵字創(chuàng)造匿名函數(shù)。
語法:lambda 參數(shù):表達(dá)式
或者 lambda 形參1,…,形參n : function(形參),入?yún)?,…,入?yún)
注意:1、lambda函數(shù)可以接收任意多個(gè)參數(shù)并且返回單個(gè)表達(dá)式的值;
2、lambda中不能包含命令,返回的表達(dá)式不能超過一個(gè)。
優(yōu)點(diǎn):1、可以省去定義函數(shù)的過程,精簡代碼;
2、對于一些抽象的、不會(huì)重復(fù)使用的函數(shù)可以用lambda進(jìn)行定義。
例子:
>>> list( map( lambda x: x*x ,[1,2,3] ) ) [1, 4, 9]
其中lamdba x : x*x 實(shí)現(xiàn)的是:def f(x): return x*x 的功能。
可以把匿名函數(shù)賦值給一個(gè)變量,再利用變量調(diào)用該函數(shù)。例如:
>>> f = lambda x:x*x >>> f(5) # 調(diào)用 >>> g = lambda x,y=2 : x*y >>> g(2,4) 8 >>> g(2) # 默認(rèn)y=2 4
可以把匿名函數(shù)作為返回值返回,例如:
return lambda x:x*x
? thanks for watching, keep on updating...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42474.html
摘要:閉包可以用來在一個(gè)函數(shù)與一組私有變量之間創(chuàng)建關(guān)聯(lián)關(guān)系。夾帶私貨外部變量返回的是函數(shù),帶私貨的函數(shù)支持將函數(shù)當(dāng)成對象使用的編程語言,一般都支持閉包。所以說當(dāng)你的裝飾器需要自定義參數(shù)時(shí),一般都會(huì)形成閉包。 Python中的閉包不是一個(gè)一說就能明白的概念,但是隨著你往學(xué)習(xí)的深入,無論如何你都需要去了解這么一個(gè)東西。 閉包的概念 我們嘗試從概念上去理解一下閉包。 在一些語言中,在函數(shù)中可以(嵌...
摘要:項(xiàng)目地址閉包在計(jì)算機(jī)科學(xué)中,閉包英語,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。 項(xiàng)目地址:https://git.io/pytips 閉包(Closure) 在計(jì)算機(jī)科學(xué)中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是...
摘要:我們說觸發(fā)了閉包的函數(shù)叫做閉包函數(shù)閉包最大的特點(diǎn)就是它可以被外層函數(shù)返回后賦值給一個(gè)變量,并且攜帶了外層函數(shù)內(nèi)定義的變量例子如下變量為函數(shù)開辟的局部命名空間內(nèi)定義的變量函數(shù)內(nèi)引用了變量的內(nèi)層函數(shù)名被當(dāng)作返回值,此時(shí)閉包規(guī)則達(dá)成。 什么是閉包? 其實(shí)我們在使用函數(shù)過程中不經(jīng)意間就會(huì)觸發(fā)閉包,因?yàn)榭倳?huì)出于某種原因會(huì)在函數(shù)內(nèi)引用或修改上一層函數(shù)的變量,這時(shí)就會(huì)觸發(fā)閉包 那么什么是閉包?其實(shí)就...
摘要:在計(jì)算機(jī)科學(xué)中,閉包又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。閉包被廣泛應(yīng)用于函數(shù)式語言中。運(yùn)用閉包可以避免對全局變量的使用。將棧頂?shù)脑厝〕觯瑒?chuàng)建元組,并將該元組進(jìn)棧。 在計(jì)算機(jī)科學(xué)中,閉包 又稱 詞法閉包 或 函數(shù)閉包,是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。閉包被廣泛應(yīng)用于函數(shù)式語言中。 從上面這段話中可以看出閉...
Python 中通過函數(shù)定義所創(chuàng)建的用戶自定義函數(shù)對象均具有一些特殊屬性,需要注意的是這里介紹的是自定義函數(shù)(function類型)的特殊屬性,而非方法(method 類型)的特殊屬性,函數(shù)和方法的特熟屬性以及默認(rèn)的返回值可能不盡相同。 對于大多數(shù)特殊屬性,可以通過下面這個(gè)例子示范一下: class Test(): def func(self, v = dog): 這里演...
閱讀 3133·2021-11-19 09:40
閱讀 2429·2021-10-14 09:42
閱讀 1697·2021-09-22 15:34
閱讀 1440·2019-08-30 15:55
閱讀 775·2019-08-29 12:59
閱讀 412·2019-08-28 18:28
閱讀 1817·2019-08-26 13:42
閱讀 1518·2019-08-26 13:29