深入了解Python全局變量和局部變量

Python中在定義及使用函數(shù)時(shí)會(huì)遇到“局部變量”和“全局變量”晾嘶。

在函數(shù)內(nèi)部定義的變量是“局部變量”幽邓;在函數(shù)外部定義的變量是“全局變量”。準(zhǔn)確地說(shuō)撤蟆,作用域是全局范圍的變量是“全局變量”奕塑;作用域是局部范圍的變量是“局部變量”。

1.作用域

作用域也叫命名空間家肯。在函數(shù)外部(比如在一個(gè)py文件中)通過(guò)賦值語(yǔ)句可以定義一個(gè)變量龄砰,例:x=1∠⑿ǎ可以將變量視為指向值的名稱寝贡,這有點(diǎn)兒像字典扒披,字典中是鍵指向值值依。

在py文件中圃泡,存在著一個(gè)“看不見(jiàn)的字典”,其中儲(chǔ)存著跟py文件相關(guān)的特殊變量(如__name__)愿险。當(dāng)定義一個(gè)變量時(shí)颇蜡,該“字典”中會(huì)自動(dòng)創(chuàng)建一個(gè)鍵值對(duì)(變量名為鍵,變量指向的值為值)辆亏,來(lái)存儲(chǔ)變量风秤。這個(gè)“看不見(jiàn)的字典”就稱為作用域或命名空間。

而當(dāng)在py文件中調(diào)用定義好的函數(shù)時(shí)會(huì)創(chuàng)建一個(gè)新的命名空間扮叨,這個(gè)命名空間只能在函數(shù)內(nèi)部使用缤弦,它是供函數(shù)內(nèi)部定義自己的變量使用的,即是函數(shù)的局部命名空間彻磁。

因此碍沐,就存在了全局命名空間和局部命名空間。這時(shí)再來(lái)看局部變量和全局變量的定義就很清楚了衷蜓。局部變量是在局部命名空間中定義的變量累提,全局變量是在全局命名空間中定義的變量。

在函數(shù)內(nèi)部磁浇,可以同時(shí)接觸到全局命名空間和局部命名空間斋陪,也因此函數(shù)可以在其內(nèi)部使用全局變量。但當(dāng)函數(shù)的局部空間中存在了與全局空間同名的變量的話置吓,函數(shù)中的局部變量就會(huì)遮蓋全局變量无虚,因此我們修改與全局變量同名的局部變量不會(huì)對(duì)全局變量產(chǎn)生任何影響,因?yàn)椴僮鞯母揪筒皇峭粋€(gè)變量衍锚。

函數(shù)內(nèi)部調(diào)用變量時(shí)友题,會(huì)優(yōu)先在自己的命名空間中查找。只有找不到時(shí)构拳,才會(huì)去全局命名空間中查找咆爽。并且函數(shù)內(nèi)定義變量時(shí),可以通過(guò)關(guān)鍵字 global 聲明其后的變量是在全局命名空間中定義的置森。

2.globals()和locals()

可以通過(guò)globals()方法訪問(wèn)全局變量斗埂,該方法返回全局命名空間的“看不見(jiàn)的字典”;通過(guò)locals()方法能夠訪問(wèn)局部變量凫海,該方法返回局部命名空間的“看不見(jiàn)的字典”呛凶。

name = 'David'? # 在函數(shù)外部定義變量,可以通過(guò)globals()方法訪問(wèn)

def print_name():? # 定義函數(shù)

? ? name = 2? ? ? # 函數(shù)內(nèi)部定義變量行贪,為局部變量漾稀,會(huì)遮蓋同名的全局變量

? ? print(locals())? # locals()返回字典模闲,里面儲(chǔ)存著局部變量,locals() = {'name': 2}

? ? print(name)

print(vars())? ? ? # vars()同globals()返回字典崭捍,里面儲(chǔ)存著全局變量

print(globals())? # globals()返回字典尸折,里面儲(chǔ)存著全局變量

print_name()

print(locals())? # 此時(shí)的locals()返回的局部命名空間即是全局命名空間

程序結(jié)果:可以看出變量name和函數(shù)print_name都是全局命名空間的成員

vars() = globals() = {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000136841685F8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Python28/Python project/project/practice/01_func_global_param.py', '__cached__': None, 'name': 'David', 'print_name': <function print_name at 0x00000136842698C8>}

3.總結(jié)

局部變量與全局變量,對(duì)應(yīng)著局部命名空間和全局命名空間殷蛇。全局命名空間里也存放著__name__实夹,__file__等跟程序文件相關(guān)的特殊變量,也可以直接調(diào)用使用它們粒梦。

函數(shù)的局部命名空間只創(chuàng)建一次亮航,哪怕是多次調(diào)用。

4.作用域補(bǔ)充

Python中的作用域一共有4種匀们,分別是:

1)L(Local):局部作用域缴淋;

2)E(Enclosing):閉包函數(shù)外的函數(shù)中(嵌套作用域);

3)G(Global):全局作用域泄朴;

4)B(Built-in):內(nèi)置作用域(內(nèi)置函數(shù)所在模塊的范圍)重抖;

在Python中,程序的變量并不是在哪個(gè)位置都可以訪問(wèn)的叼旋,訪問(wèn)的權(quán)限決定于這個(gè)變量是在哪個(gè)作用域中被賦值的仇哆。并且變量所在的作用域也決定了在程序的哪一部分可以訪問(wèn)到它。

Python中的作用域遵循LEGB原則:查找變量夫植,先在L作用域查找讹剔,找不到便會(huì)去E作用域查找,再找不到去G作用域查找详民,再者去B作用域查找延欠。

Python 中只有模塊(module),類(lèi)(class)以及函數(shù)(def沈跨、lambda)才會(huì)引入新的作用域由捎。其它的代碼塊(如 if/elif/else/、try/except饿凛、for/while等)不會(huì)引入新的作用域狞玛,也因此這些語(yǔ)句內(nèi)定義的變量,外部也可以直接訪問(wèn)涧窒。

Python的內(nèi)置作用域心肪,作用范圍很廣,每新建一個(gè)py文件它就處于內(nèi)置作用域中纠吴。通過(guò)以下方式可以查看內(nèi)置作用域:

import builtins

print(dir(builtins))

# 返回一個(gè)列表硬鞍,其中包含內(nèi)置作用域中各個(gè)內(nèi)置對(duì)象,包括:

1)各種異常類(lèi);比如'SyntaxError', 'SyntaxWarning', 'SystemError'固该;

2)各種特殊屬性锅减;比如'__name__', '__package__', '__spec__';

3)各個(gè)內(nèi)置函數(shù)伐坏;比如'id', 'input', 'int', 'isinstance'怔匣;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市著淆,隨后出現(xiàn)的幾起案子劫狠,更是在濱河造成了極大的恐慌拴疤,老刑警劉巖永部,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異呐矾,居然都是意外死亡苔埋,警方通過(guò)查閱死者的電腦和手機(jī)蜒犯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)玉工,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人狭郑,你說(shuō)我怎么就攤上這事∧豆恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)习劫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)谤狡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任盈罐,我火速辦了婚禮钓葫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己诱告,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布佛吓。 她就那樣靜靜地躺著,像睡著了一般逸贾。 火紅的嫁衣襯著肌膚如雪津滞。 梳的紋絲不亂的頭發(fā)上铝侵,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音触徐,去河邊找鬼咪鲜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锌介,可吹牛的內(nèi)容都是我干的嗜诀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼孔祸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了发皿?” 一聲冷哼從身側(cè)響起崔慧,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎穴墅,沒(méi)想到半個(gè)月后惶室,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玄货,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年皇钞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片松捉。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夹界,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隘世,到底是詐尸還是另有隱情可柿,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布丙者,位于F島的核電站复斥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏械媒。R本人自食惡果不足惜目锭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痢虹,春花似錦键俱、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至臭埋,卻和暖如春踪央,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓢阴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工畅蹂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荣恐。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓液斜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親叠穆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子少漆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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