内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀-創(chuàng)新互聯(lián)

1 函數(shù)嵌套

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的濮陽(yáng)縣網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一個(gè)函數(shù)中存在另外一個(gè)函數(shù)(定義/調(diào)用),這種方式我們稱(chēng)之為函數(shù)嵌套。所以:函數(shù)的嵌套主要分為嵌套調(diào)用,以及嵌套定義。

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

注意:在函數(shù)的內(nèi)部定義函數(shù),只能在函數(shù)內(nèi)部進(jìn)行調(diào)用,在其他地方是無(wú)法進(jìn)行調(diào)用,強(qiáng)行調(diào)用就會(huì)提示NameError異常,所以說(shuō)函數(shù)是有可見(jiàn)范圍的,這就涉及到了作用域了

2 作用域

一個(gè)標(biāo)識(shí)符的可見(jiàn)范圍,叫做標(biāo)識(shí)符的作用域。一般常說(shuō)的是變量的作用域。根據(jù)作用的范圍主要分為全局作用域和局部作用域。

全局作用域:在整個(gè)程序運(yùn)行環(huán)境中都可見(jiàn)

局部作用域:在函數(shù)、類(lèi)的內(nèi)部可見(jiàn),并且使用范圍不能超過(guò)所在的局部作用域(比如在函數(shù)內(nèi)部定義了一個(gè)變量x,我在全局使用變量x是不行的。)

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

全局變量x在全局生效,所以內(nèi)部函數(shù)inner是可以打印x的

局部變量y只在inner內(nèi)部生效,所以在全局print(y) 是無(wú)法調(diào)用局部變量y的

觀察下面的例子:

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

代碼是從上到下執(zhí)行的,所欲這樣寫(xiě)也沒(méi)什么毛病,但是這里這個(gè)例子是無(wú)法執(zhí)行的,為什么呢?

x作為全局變量,在inner內(nèi)部是可見(jiàn)的

在定義函數(shù)的階段,Python的函數(shù)是作為一個(gè)整體一起被解釋的。

inner函數(shù)在解釋時(shí),解釋器發(fā)現(xiàn)在inner內(nèi)部對(duì)x進(jìn)行了定義(x += 1),那么它就不會(huì)在調(diào)用全局變量x,而是標(biāo)識(shí)x是局部定義的變量

而在執(zhí)行x+=1的時(shí)候,inner內(nèi)部的x還沒(méi)有被定義,所以會(huì)提示x在定義前被執(zhí)行了。(x += 1 --> x = x + 1 ,預(yù)先求 x + 1 時(shí)提示的)。

如何解決呢?有兩種方法:更換變量名稱(chēng)、聲明當(dāng)前變量非本地變量(global)

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

2.1 global關(guān)鍵字

我們通過(guò)在函數(shù)內(nèi)部使用global關(guān)鍵字來(lái)聲明一個(gè)變量不是局部變量,而是一個(gè)全局變量。

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

雖然全局變量x,在全局沒(méi)有被定義,但是由于在函數(shù)內(nèi)部使用了global關(guān)鍵字,所以x就變成了全局變量了。使用了global關(guān)鍵字,那么之前的例子就可以進(jìn)行如下修改了

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

針對(duì)global的總結(jié):

外部作用域變量在內(nèi)部作用域是可見(jiàn)的,但是不要在內(nèi)部函數(shù)中直接使用或者修改,因?yàn)楹瘮?shù)的目的就是為了封裝,盡量與外界隔離。

如果函數(shù)需要使用外部全局變量,請(qǐng)盡量使用函數(shù)的形參定義,在調(diào)用時(shí)傳遞實(shí)參來(lái)使用

建議不要使用global。

3 閉包

在很多編程語(yǔ)言中都存在閉包的概念,那什么是閉包呢?閉包其實(shí)就是一個(gè)概念,出現(xiàn)在嵌套函數(shù)中,指的是:內(nèi)層函數(shù)引用到了外層函數(shù)的自由變量,就形成了閉包

自由變量:未在本地作用域中定義的變量,比如在嵌套函數(shù)的外層定義的變量(非全局變量),對(duì)內(nèi)層來(lái)說(shuō),這個(gè)變量就叫做自由變量。

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

注意:上面這個(gè)例子比較特殊,首先它是一個(gè)閉包,在inner函數(shù)內(nèi)引用了外層函數(shù)的自由變量C。因?yàn)檫@里的c是一個(gè)引用類(lèi)型,我們可以直接通過(guò)c來(lái)操作c中的元素,但是沒(méi)辦法對(duì)c本身進(jìn)行修改,即c += [1,3]??此剖橇斜砥唇樱撬鼤?huì)重新對(duì)c進(jìn)行聲明,這就引發(fā)了之前的問(wèn)題,內(nèi)部函數(shù)inner沒(méi)有定義c,所以會(huì)報(bào)錯(cuò)!所以當(dāng)c不是引用類(lèi)型的話,我們就沒(méi)辦法修改了嗎?當(dāng)然不是,可以使用global把c聲明為全局變量,但是這就不是閉包了,所以這里就需要使用nonlocal了(python 3 特有)。

疑問(wèn)?我們都說(shuō)函數(shù)執(zhí)行完畢后,函數(shù)的內(nèi)部變量將會(huì)被回收,這里的outer執(zhí)行完畢后,那么變量c應(yīng)該會(huì)被回收啊,為什么還能被內(nèi)層的inner找到呢?這是因?yàn)樵诙x階段,解釋器解釋到inner函數(shù)時(shí),由于函數(shù)是作為一個(gè)整體被解析的,所以解釋器知道在inner內(nèi)部引用了外部的變量,所以在執(zhí)行函數(shù)outer時(shí),并不會(huì)回收已被內(nèi)部函數(shù)inner引用的自由變量c。

3.1 nonlocal關(guān)鍵字

使用了nonlocal關(guān)鍵字,將變量標(biāo)記為不在本地作用域定義,而在上一級(jí)局部作用域中定義,但不能是全局作用域中定義。

nonlocal只能用在嵌套函數(shù)的內(nèi)部

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

4 默認(rèn)值的作用域

在Python中,一切皆對(duì)象,函數(shù)也不列外,當(dāng)我們給函數(shù)定義默認(rèn)值時(shí),Python會(huì)把它存放在函數(shù)的屬性中,這個(gè)屬性值就伴隨這個(gè)函數(shù)對(duì)象的整個(gè)生命周期。

foo.__defaults__屬性查看函數(shù)的默認(rèn)值屬性

Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀

仔細(xì)查看輸出結(jié)果,發(fā)現(xiàn)函數(shù)地址沒(méi)有變,也就是說(shuō)函數(shù)這個(gè)對(duì)象沒(méi)有變,但是我們發(fā)現(xiàn)每次它的__default__屬性都會(huì)發(fā)生變化,這是為什么呢?這是因?yàn)閟ed和list的默認(rèn)值都是引用類(lèi)型,它們引用的都是函數(shù)在定義時(shí)定義的默認(rèn)值中。 雖然函數(shù)執(zhí)行完就釋放了內(nèi)存空間,也是由于引用類(lèi)型,指向默認(rèn)空間的指針沒(méi)了,但是已經(jīng)在調(diào)用時(shí)改變了默認(rèn)值空間的對(duì)象中的元素,所以在下一次再次調(diào)用時(shí)此時(shí)默認(rèn)值空間的元素已經(jīng)被改變了。所以當(dāng)函數(shù)的默認(rèn)值為引用類(lèi)型時(shí),這點(diǎn)要特別的注意了

解決辦法:

在定義時(shí)使用引用類(lèi)型時(shí),在函數(shù)內(nèi)部使用前先進(jìn)行copy。

在定義函數(shù)時(shí)默認(rèn)使用None值,在函數(shù)內(nèi)判斷如果是None則開(kāi)辟一個(gè)引用類(lèi)型。

5 變量名解析原則LEGB

變量的解析原則,也可以理解為變量的查找順序:

L(Local): 本地作用域、局部作用域的local命名空間。函數(shù)調(diào)用是創(chuàng)建,調(diào)用結(jié)束消亡

E(Enclosing): Python 2.2時(shí)引入嵌套函數(shù),實(shí)現(xiàn)了閉包,這個(gè)就是嵌套函數(shù)的外部函數(shù)的命名空間

G(Global): 全局作用域,即一個(gè)模塊的命名空間。模塊被import時(shí)創(chuàng)建,解釋器退出時(shí)消亡

B(Build-in): 內(nèi)置模塊的命名空間,生命周期從Python解釋器啟動(dòng)時(shí)創(chuàng)建到解釋器退出時(shí)消亡。例如print函數(shù)、open函數(shù)等。

變量查找的規(guī)則為 L > E > G > B,即:先本地后嵌套再全局最后是內(nèi)置函數(shù)中

6 函數(shù)的銷(xiāo)毀

全局函數(shù):

重新定義同名函數(shù)

del 語(yǔ)句刪除函數(shù)名稱(chēng),函數(shù)對(duì)象引用計(jì)數(shù)減1

程序結(jié)束時(shí)

局部函數(shù):

重新在上級(jí)作用域定義同名函數(shù)

del 語(yǔ)句刪除函數(shù)名稱(chēng),函數(shù)對(duì)象的引用計(jì)數(shù)減1

上級(jí)作用域銷(xiāo)毀時(shí)

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

標(biāo)題名稱(chēng):Python函數(shù)嵌套-作用域-閉包-LEGB-函數(shù)銷(xiāo)毀-創(chuàng)新互聯(lián)
URL地址:http://www.rwnh.cn/article48/cspoep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、微信公眾號(hào)企業(yè)建站、面包屑導(dǎo)航網(wǎng)站策劃、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
共和县| 衡阳市| 万安县| 皋兰县| 兴文县| 富锦市| 米脂县| 诸暨市| 双峰县| 邯郸市| 游戏| 井冈山市| 吉首市| 南和县| 长沙市| 区。| 漾濞| 招远市| 新野县| 花垣县| 丽江市| 南康市| 兴化市| 吕梁市| 汶上县| 汝城县| 正阳县| 通江县| 调兵山市| 泊头市| 青铜峡市| 精河县| 乐陵市| 龙胜| 阿荣旗| 措美县| 鲁甸县| 钟祥市| 贵阳市| 荣成市| 盐城市|