摘要:我們說觸發(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í)我們?cè)谑褂煤瘮?shù)過程中不經(jīng)意間就會(huì)觸發(fā)閉包,因?yàn)榭倳?huì)出于某種原因會(huì)在函數(shù)內(nèi)引用或修改上一層函數(shù)的變量,這時(shí)就會(huì)觸發(fā)閉包
那么什么是閉包?其實(shí)就是函數(shù)嵌套時(shí)觸發(fā)的一種規(guī)則,當(dāng)前函數(shù)引用到上一層函數(shù)的局部命名空間的變量并且函數(shù)本身被當(dāng)成對(duì)象返回時(shí)就觸發(fā)該規(guī)則。
我們說觸發(fā)了閉包的函數(shù)叫做閉包函數(shù)
閉包最大的特點(diǎn)就是它可以被外層函數(shù)返回后賦值給一個(gè)變量,并且攜帶了外層函數(shù)內(nèi)定義的變量
例子如下:
def func1(): a = 2 #變量a為函數(shù)func1()開辟的局部命名空間內(nèi)定義的變量 def func2(x): return x**a #函數(shù)fun2()內(nèi)引用了變量a print("func2的id:",id(func2)) return func2 #內(nèi)層函數(shù)名被當(dāng)作返回值,此時(shí)閉包規(guī)則達(dá)成。 res = func1() # 此時(shí)res等同于func2,我們可以看看他們的id完全相同 print("res的id: ",id(res)) print(res(3)) del func1 print("刪除函數(shù)func1之后:",res(5)) print(res.__closure__) print(type(res.__closure__[0])) print(res.__closure__[0].cell_contents) #此時(shí),如果函數(shù)func2()沒有引用外部函數(shù)變量a,我們可以試著把return x**a這句改成return x,這時(shí)函數(shù)func2就沒有觸發(fā)閉包規(guī)則 #此時(shí)如果再次打印res.__closure__,你會(huì)發(fā)現(xiàn)輸出值為None
從下面輸出結(jié)果可以看出,即使刪除了函數(shù)func1,理論上應(yīng)該消失的變量a依然可以使用(理論上a對(duì)應(yīng)的局部空間消失了,則a應(yīng)消失),變量a之所以仍然可以被引用,是因?yàn)殚]包規(guī)則的作用,外部函數(shù)的局部變量可以被內(nèi)部函數(shù)引用,即使外部函數(shù)已經(jīng)返回了。
其實(shí)函數(shù)本身也是對(duì)象,而對(duì)象又有很多屬性,其中和閉包相關(guān)的就是 closure 屬性。
closure 屬性定義的是一個(gè)包含 cell 對(duì)象的元組,其中元組中的每一個(gè) cell 對(duì)象用來保存作用域中變量的值。
func2的id: 139940709362136 res的id: 139940709362136 9 刪除函數(shù)func1之后: 25 #我們來打印一下res的__closure__屬性,可以看出它是由cell對(duì)象組成的元組 (,) | #打印類型結(jié)果就是元組 2 #打印cell中的值可以看出,這個(gè)cell對(duì)象中存儲(chǔ)的變量值為2
觸發(fā)閉包后,實(shí)現(xiàn)了引用上層局部命名空間變量的同時(shí)又不依賴于該局部空間,即使該變量所在的函數(shù)被刪除了,閉包函數(shù)依然可以使用它,實(shí)際上閉包函數(shù)把它保存在了__closure__屬性中。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42575.html
摘要:在內(nèi)置命名空間不能使用全局和局部的名字。可以形象地理解成內(nèi)置命名空間具有最高級(jí)別,不需要定義就可以使用,全局命名空間次之,最低級(jí)是局部命名空間。 python中的命名空間分三種: 內(nèi)置的命名空間,在啟動(dòng)解釋器的時(shí)候自動(dòng)加載進(jìn)內(nèi)存的各種名字所在的空間,比如print,input等不需要定義就可以使用的名字 全局命名空間,就是從上到下所有我們定義的變量名和函數(shù)名所在的空間,是在程序從上到下...
摘要:定義函數(shù)中的函數(shù)使用關(guān)鍵字定義,格式為函數(shù)名形參函數(shù)語句塊函數(shù)名只能包含字符串下劃線和數(shù)字且不能以數(shù)字開頭。所以默認(rèn)參數(shù)還是放在后面合適。 定義函數(shù) python中的函數(shù)使用關(guān)鍵字 def 定義,格式為: def 函數(shù)名(形參): 函數(shù)語句塊 函數(shù)名只能包含字符串、下劃線和數(shù)字且不能以數(shù)字開頭。函數(shù)的形參分為:位置參數(shù)、默認(rèn)參數(shù)(自帶默認(rèn)值的參數(shù))、動(dòng)態(tài)參數(shù)return是關(guān)鍵字...
摘要:事實(shí)上語言當(dāng)中有的內(nèi)容,比如函數(shù)循環(huán)結(jié)構(gòu)體宏等等內(nèi)容,也都有,所以大家千萬不要認(rèn)為語言白學(xué)了哈因?yàn)橹耙呀?jīng)完整更新過語言的博客有需要可以往前翻,所以這里直接介紹相對(duì)語言當(dāng)中新增的內(nèi)容,而本章引入的內(nèi)容是的關(guān)鍵字命名空間缺省參數(shù)函數(shù)重載。 ...
摘要:最近看前端都展開了幾場而我大知乎最熱語言還沒有相關(guān)。有關(guān)書籍的介紹,大部分截取自是官方介紹。但從開始,標(biāo)準(zhǔn)庫為我們提供了模塊,它提供了和兩個(gè)類,實(shí)現(xiàn)了對(duì)和的進(jìn)一步抽象,對(duì)編寫線程池進(jìn)程池提供了直接的支持。 《流暢的python》閱讀筆記 《流暢的python》是一本適合python進(jìn)階的書, 里面介紹的基本都是高級(jí)的python用法. 對(duì)于初學(xué)python的人來說, 基礎(chǔ)大概也就夠用了...
閱讀 2096·2023-04-25 15:24
閱讀 1606·2019-08-30 12:55
閱讀 1641·2019-08-29 15:27
閱讀 497·2019-08-26 17:04
閱讀 2445·2019-08-26 10:59
閱讀 1828·2019-08-26 10:44
閱讀 2230·2019-08-22 16:15
閱讀 2614·2019-08-22 15:36