Python變量作用域

在程序中定義一個(gè)變量時(shí)变泄,這個(gè)變量是有作用范圍的令哟,變量的作用范圍被稱為它的作用域。

根據(jù)定義變量的位置妨蛹,變量分為兩種:

局部變量:在函數(shù)中定義的變量屏富,包括參數(shù),都被稱為局部變量蛙卤。

全局變量:在函數(shù)外面狠半、全局范圍內(nèi)定義的變量,被稱為全局變量颤难。

每個(gè)函數(shù)在執(zhí)行時(shí)神年,系統(tǒng)都會(huì)為該函數(shù)分配一塊“臨時(shí)內(nèi)存空間”,所有的局部變量都被保存在這塊臨時(shí)內(nèi)存空間內(nèi)行嗤。當(dāng)函數(shù)執(zhí)行完成后已日,這塊內(nèi)存空間就被釋放了,這些局部變量也就失效了栅屏,因此離開函數(shù)之后就不能再訪問局部變量了飘千。

全局變量意味著它們可以在所有函數(shù)內(nèi)被訪問堂鲜。

不管是在函數(shù)的局部范圍內(nèi)還是在全局范圍內(nèi),都可能存在多個(gè)變量护奈,每個(gè)變量“持有”該變量的值缔莲。從這個(gè)角度來看,不管是局部范圍還是全局范圍霉旗,這些變量和它們的值就像一個(gè)“看不見”的字典酌予,其中變量名就是字典的 key,變量值就是字典的 value奖慌。

實(shí)際上抛虫,Python 提供了如下三個(gè)工具函數(shù)來獲取指定范圍內(nèi)的“變量字典”:

globals():該函數(shù)返回全局范圍內(nèi)所有變量組成的“變量字典”。

locals():該函數(shù)返回當(dāng)前局部范圍內(nèi)所有變量組成的“變量字典”简僧。

vars(object):獲取在指定對(duì)象范圍內(nèi)所有變量組成的“變量字典”建椰。如果不傳入object 參數(shù),vars() 和 locals() 的作用完全相同岛马。

globals() 和 locals() 看似完全不同棉姐,但它們實(shí)際上也是有聯(lián)系的,關(guān)于這兩個(gè)函數(shù)的區(qū)別和聯(lián)系大致有以下兩點(diǎn):

locals() 總是獲取當(dāng)前局部范圍內(nèi)所有變量組成的“變量字典”啦逆,因此伞矩,如果在全局范圍內(nèi)(在函數(shù)之外)調(diào)用 locals() 函數(shù),同樣會(huì)獲取全局范圍內(nèi)所有變量組成的“變量字典”夏志;而 globals() 無論在哪里執(zhí)行乃坤,總是獲取全局范圍內(nèi)所有變量組成的“變量字典”。

一般來說沟蔑,使用 locals() 和 globals() 獲取的“變量字典”只應(yīng)該被訪問湿诊,不應(yīng)該被修改。但實(shí)際上瘦材,不管是使用 globals() 還是使用 locals() 獲取的全局范圍內(nèi)的“變量字典”厅须,都可以被修改,而這種修改會(huì)真正改變?nèi)肿兞勘旧恚旱ㄟ^ locals() 獲取的局部范圍內(nèi)的“變量字典”食棕,即使對(duì)它修改也不會(huì)影響局部變量朗和。

下面程序示范了如何使用 locals()、globals() 函數(shù)訪問局部范圍和全局范圍內(nèi)的“變量字典”:

def?test?():

age?=?20

#?直接訪問age局部變量

print(age)?#?輸出20

#?訪問函數(shù)局部范圍的“變量數(shù)組”

print(locals())?#?{'age':?20}

#?通過函數(shù)局部范圍的“變量數(shù)組”訪問age變量

print(locals()['age'])?#?20

#?通過locals函數(shù)局部范圍的“變量數(shù)組”改變age變量的值

locals()['age']?=?12

#?再次訪問age變量的值

print('xxx',?age)?#?依然輸出20

#?通過globals函數(shù)修改x全局變量

globals()['x']?=?19

x?=?5

y?=?20

print(globals())?#?{...,?'x':?5,?'y':?20}

#?在全局訪問內(nèi)使用locals函數(shù)簿晓,訪問的是全局變量的“變量數(shù)組”

print(locals())?#?{...,?'x':?5,?'y':?20}

#?直接訪問x全局變量

print(x)?#?5

#?通過全局變量的“變量數(shù)組”訪問x全局變量

print(globals()['x'])?#?5

#?通過全局變量的“變量數(shù)組”對(duì)x全局變量賦值

globals()['x']?=?39

print(x)?#?輸出39

#?在全局范圍內(nèi)使用locals函數(shù)對(duì)x全局變量賦值

locals()['x']?=?99

print(x)?#?輸出99

從上面程序可以清楚地看出眶拉,locals() 函數(shù)用于訪問特定范圍內(nèi)的所有變量組成的“變量字典”,而 globals() 函數(shù)則用于訪問全局范圍內(nèi)的全局變量組成的“變量字典”抢蚀。

全局變量默認(rèn)可以在所有函數(shù)內(nèi)被訪問镀层,但如果在函數(shù)中定義了與全局變量同名的變量,此時(shí)就會(huì)發(fā)生局部變量遮蔽(hide)全局變量的情形皿曲。例如如下程序:

name?=?'Charlie'

def?test?():

#?直接訪問name全局變量

print(name)?#?Charlie

test()

print(name)

上面程序中唱逢,第 4 行直接訪問 name 變量,這是允許的屋休,此時(shí)程序?qū)?huì)輸出 Charlie坞古。如果在此之后增加如下一行代碼:

name?=?'孫悟空'

再次運(yùn)行該程序,將會(huì)看到如下錯(cuò)誤:

UnboundLocalError?:?local?variable?‘name’?referenced?before?assignment

該錯(cuò)誤提示粗體字代碼所訪問的 name 變量還未定義劫樟。這是什么原因呢痪枫?這正是由于程序在 test() 函數(shù)中增加了“name='孫悟空'”一行代碼造成的。

Python 語法規(guī)定叠艳,在函數(shù)內(nèi)部對(duì)不存在的變量賦值時(shí)奶陈,默認(rèn)就是重新定義新的局部變量。因此這行代碼相當(dāng)于重新定義了 name 局部變量附较,這樣 name 全局變量就被遮蔽了吃粒,所以程序會(huì)報(bào)錯(cuò)。

為了避免這個(gè)問題拒课,可以通過以下兩種方式來修改上面程序:

訪問被遮蔽的全局變量徐勃。如果希望程序依然能訪問 name 全局變量,且在函數(shù)中可重新定義 name 局部變量早像,也就是在函數(shù)中可以訪問被遮蔽的全局變量僻肖,此時(shí)可通過 globals() 函數(shù)來實(shí)現(xiàn),將上面程序改為如下形式即可:

name?=?'Charlie'

def?test?():

#?直接訪問name全局變量

print(globals()['name'])??#?Charlie

name?=?'孫悟空'

test()

print(name)??#?Charlie

在函數(shù)中聲明全局變量卢鹦。為了避免在函數(shù)中對(duì)全局變量賦值(不是重新定義局部變量)臀脏,可使用 global 語句來聲明全局變量。因此冀自,可將程序改為如下形式:

name?=?'Charlie'

def?test?():

#?聲明name是全局變量谁榜,后面的賦值語句不會(huì)重新定義局部變量

global?name

#?直接訪問name全局變量

print(name)??#?Charlie

name?=?'孫悟空'

test()

print(name)??#?孫悟空

增加了“global name”聲明之后,程序會(huì)把 name 變量當(dāng)成全局變量凡纳,這意味著 test() 函數(shù)后面對(duì) name 賦值的語句只是對(duì)全局變量賦值窃植,而不是重新定義局部變量。

Python變量作用域-Python學(xué)習(xí)網(wǎng)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末荐糜,一起剝皮案震驚了整個(gè)濱河市巷怜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌暴氏,老刑警劉巖延塑,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異答渔,居然都是意外死亡关带,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宋雏,“玉大人芜飘,你說我怎么就攤上這事∧プ埽” “怎么了嗦明?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚪燕。 經(jīng)常有香客問我娶牌,道長,這世上最難降的妖魔是什么馆纳? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任诗良,我火速辦了婚禮,結(jié)果婚禮上鲁驶,老公的妹妹穿的比我還像新娘鉴裹。我一直安慰自己,他們只是感情好灵嫌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布壹罚。 她就那樣靜靜地躺著,像睡著了一般寿羞。 火紅的嫁衣襯著肌膚如雪猖凛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天绪穆,我揣著相機(jī)與錄音辨泳,去河邊找鬼。 笑死玖院,一個(gè)胖子當(dāng)著我的面吹牛菠红,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播难菌,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼试溯,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了郊酒?” 一聲冷哼從身側(cè)響起遇绞,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燎窘,沒想到半個(gè)月后摹闽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褐健,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年付鹿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舵匾,死狀恐怖俊抵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纽匙,我是刑警寧澤务蝠,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布拍谐,位于F島的核電站烛缔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏轩拨。R本人自食惡果不足惜践瓷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望亡蓉。 院中可真熱鬧晕翠,春花似錦、人聲如沸砍濒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爸邢。三九已至樊卓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杠河,已是汗流浹背碌尔。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留券敌,地道東北人唾戚。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像待诅,于是被迫代替她去往敵國和親叹坦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1卑雁、引言 最近在刷leetcode題的時(shí)候募书,遇到一個(gè)求最長回文子串的題目,于是序厉,我寫了如下的代碼: 哎呀锐膜,寫了兩個(gè)...
    文哥的學(xué)習(xí)日記閱讀 14,324評(píng)論 6 32
  • 變量作用域(scope)在Python中是一個(gè)容易掉坑的地方。Python的作用域一共有4中弛房,分別是: L (Lo...
    牧歌_閱讀 14,042評(píng)論 2 24
  • 一媒咳、變量作用域 定義:在Python程序中創(chuàng)建、改變种远、查找變量名時(shí)涩澡,都是在一個(gè)保存變量名的空間中進(jìn)行,我們稱之為命...
    Xyxtank閱讀 233評(píng)論 0 0
  • 她是一個(gè)漂亮的女孩子粥帚。 她的身邊從來不愁男人,雖然她不會(huì)對(duì)他們正眼看一回限次,可是女人的虛榮心…… 太多太多的男人了芒涡,...
    唐詩傅閱讀 253評(píng)論 0 0
  • 大概明白這本為什么暢銷了。這本在毛姆大爺絮絮叨叨的敘事風(fēng)格里面已經(jīng)可以算得上是“波瀾起伏”了卖漫。更重要的是费尽,滿足了大...
    wanzi_763閱讀 148評(píng)論 0 0