溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

global和nonlocal在Python中有什么區(qū)別

發(fā)布時(shí)間:2021-02-04 17:47:36 來源:億速云 閱讀:170 作者:Leah 欄目:開發(fā)技術(shù)

本篇文章為大家展示了global和nonlocal在Python中有什么區(qū)別,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

兩個(gè)關(guān)鍵詞都用于允許在一個(gè)局部作用域中使用外層的變量。

  • global 表示將變量聲明為全局變量

  • nonlocal 表示將變量聲明為外層變量(外層函數(shù)的局部變量,而且不能是全局變量)

注意:我使用的是Python3.6.3,可能和Python2有不同的地方,并未確認(rèn)。

考慮到文章比較啰嗦,先把結(jié)論貼出來,避免浪費(fèi)大家的時(shí)間:

第一,兩者的功能不同。global關(guān)鍵字修飾變量后標(biāo)識(shí)該變量是全局變量,對(duì)該變量進(jìn)行修改就是修改全局變量,而nonlocal關(guān)鍵字修飾變量后標(biāo)識(shí)該變量是上一級(jí)函數(shù)中的局部變量,如果上一級(jí)函數(shù)中不存在該局部變量,nonlocal位置會(huì)發(fā)生錯(cuò)誤(最上層的函數(shù)使用nonlocal修飾變量必定會(huì)報(bào)錯(cuò))。

第二,兩者使用的范圍不同。global關(guān)鍵字可以用在任何地方,包括最上層函數(shù)中和嵌套函數(shù)中,即使之前未定義該變量,global修飾后也可以直接使用,而nonlocal關(guān)鍵字只能用于嵌套函數(shù)中,并且外層函數(shù)中定義了相應(yīng)的局部變量,否則會(huì)發(fā)生錯(cuò)誤(見第一)。

接下來是得到結(jié)論的過程,有興趣的可以瀏覽一下。

我們先來看一個(gè)代碼片段,看看默認(rèn)情況下輸出結(jié)果是什么(不敢恭維CSDN顯示代碼的格式,這里使用圖片,如果要驗(yàn)證,得麻煩各位動(dòng)動(dòng)指頭了)。

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

上面的代碼片段中沒有使用global或nonlocal關(guān)鍵字,是為了看一下默認(rèn)情況下的輸出結(jié)果。

可以看到變量x在三次輸出中是同一個(gè)變量(值相同,地址也相同),都是全局變量,在print函數(shù)中使用三個(gè)參數(shù)是為了方便識(shí)別變量,第一個(gè)參數(shù)是print運(yùn)行的位置,第二個(gè)參數(shù)是變量x保存的值,第三個(gè)參數(shù)是變量x保存的值的地址(這個(gè)有待考證)。

如果我們?cè)趂unc函數(shù)中修改x的值呢?

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到func函數(shù)中x的值和地址都變了,但沒有影響函數(shù)外邊的x的值和地址(main1和main2的數(shù)據(jù)相同)。所以func函數(shù)內(nèi)的x變量和函數(shù)外的x變量是兩個(gè)變量,而func內(nèi)的x變量是局部變量,修改它的值不影響全局變量。

第一回合:在函數(shù)內(nèi)部使用了與全局變量同名的變量,如果不對(duì)該變量賦值(修改變量),那么該變量就是全局變量,如果對(duì)該變量進(jìn)行賦值,那么該變量就是局部變量。

如果我們想在func函數(shù)內(nèi)修改全局變量x呢?我們先試試用global(全局)。

global和nonlocal在Python中有什么區(qū)別

運(yùn)行后報(bào)錯(cuò),提示語法錯(cuò)誤。原來global修飾變量時(shí)不能直接賦值,修改為如下:

global和nonlocal在Python中有什么區(qū)別

運(yùn)行結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到main1位置的x和func內(nèi)部func1位置的x是同一個(gè)值,但和func內(nèi)部的func2以及main2位置的x不一樣了,反而是main2處的x和func內(nèi)部的x變量是同一個(gè)。

第二回合:global關(guān)鍵字修飾函數(shù)內(nèi)部變量后標(biāo)志其是全局變量(這里不能說global將x從局部變量改為了全局變量),如果用global修飾函數(shù)內(nèi)的變量,必須在使用該變量前進(jìn)行修飾(否則會(huì)發(fā)生變量未定義的錯(cuò)誤,請(qǐng)你自己嘗試一下)。

我們?cè)囋噉onlocal關(guān)鍵字呢?

global和nonlocal在Python中有什么區(qū)別

報(bào)錯(cuò)了,無法使用nonlocal關(guān)鍵字。

接下來我們看看怎樣使用nonlocal關(guān)鍵字。

我們先添加一個(gè)嵌套函數(shù):

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到嵌套函數(shù)內(nèi)默認(rèn)使用的也是全局變量。我們?cè)趂unc函數(shù)中修改一下x的值試試。

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到在func函數(shù)中修改x后,x被標(biāo)識(shí)成局部變量,它的改變并沒有影響全局變量x,但嵌套函數(shù)ifunc中的x受到了影響,顯示ifunc中的x是func函數(shù)中的局部變量。

我們?cè)倮^續(xù)修改一下ifunc中x的值。

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到在ifunc修改x的之后即沒有影響func中的局部變量x,也沒有影響全局變量x,ifunc中的x是函數(shù)ifunc自己的局部變量。

第三回合:如果在嵌套函數(shù)和函數(shù)(這里指包含嵌套函數(shù)的那個(gè)函數(shù))中存在和全局變量同名的變量,如果直接使用,而不修改變量的值,那么這三個(gè)位置的變量使用的是同一個(gè)全局變量,如果在函數(shù)中修改了變量值,那么該變量會(huì)被標(biāo)識(shí)為該函數(shù)的局部變量,嵌套函數(shù)直接使用時(shí)使用的是該函數(shù)的局部變量。如果在嵌套函數(shù)中修改同名變量的值,那么嵌套函數(shù)中的該變量會(huì)被標(biāo)識(shí)為該嵌套函數(shù)的局部變量,它的修改不影響函數(shù)中同名變量和全局變量。

我們?cè)谇短缀瘮?shù)中添加global關(guān)鍵字試試。

先不修改ifunc中x的值:

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看出嵌套函數(shù)ifunc中的x是全局變量。

再修改一下ifunc中x的值試試:

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看出嵌套函數(shù)中x是全局變量,但它的修改沒有影響到func函數(shù)中的同名局部變量。

我們?cè)谇斑呉呀?jīng)發(fā)現(xiàn)在func函數(shù)中直接使用nonlocal關(guān)鍵字發(fā)生了報(bào)錯(cuò),我們?cè)僭囋囋趇func中使用nonlocal關(guān)鍵字:

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

可以看到nonlocal修飾后,ifunc中的x和func中的x是同一個(gè)變量,ifunc中修改x的值影響了func中的x(因?yàn)槭且粋€(gè)變量),但并沒有影響全局變量x。

再擴(kuò)展一下:

在func函數(shù)中用global修飾x并修改ifunc中x的值,看看有什么變化:

global和nonlocal在Python中有什么區(qū)別

輸出結(jié)果:

global和nonlocal在Python中有什么區(qū)別

我們?cè)儆胣onlocal修飾一下ifunc函數(shù)中的x:

global和nonlocal在Python中有什么區(qū)別

運(yùn)行時(shí)發(fā)生報(bào)錯(cuò),提示沒有為ifunc中的x找到綁定。

第四回合:global可以在任何地方修飾變量,而且被global修飾的變量直接被標(biāo)識(shí)為全局變量,對(duì)該變量修改會(huì)影響全局變量的值,但不影響函數(shù)中未被global修飾的同名變量(依然是局部變量),nonlocal只能在嵌套函數(shù)(可能還有其他的地方,我還沒有檢查)中使用,用于標(biāo)識(shí)嵌套函數(shù)中的變量是包含該嵌套函數(shù)的函數(shù)中的同名變量,在嵌套函數(shù)中修改變量會(huì)影響函數(shù)中的變量。如果在函數(shù)中使用global修飾了變量,那么在嵌套函數(shù)中用nonlocal修飾同名變量會(huì)發(fā)生報(bào)錯(cuò),因?yàn)閚onlocal表示該變量在函數(shù)中已經(jīng)定義,但檢查時(shí)因?yàn)橥兞勘籫lobal修飾為全局變量,所以不存在同名的局部變量,從而導(dǎo)致錯(cuò)誤。

上述內(nèi)容就是global和nonlocal在Python中有什么區(qū)別,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI