淺析Python中全局變量和局部變量的使用
什么是全局變量和局部變量?
在Python中,主程序和每個(gè)函數(shù)都擁有自己的命名空間(namespace)。簡(jiǎn)單的區(qū)分規(guī)則如下:
- 主程序定義了“全局”的命名空間,主程序中定義的變量是“全局變量”。
- 每個(gè)函數(shù)定義了“局部”的命名空間,函數(shù)內(nèi)部定義的變量就是“局部變量”。
- 每個(gè)命名空間中的變量名稱都是“唯一的”。不同命名空間內(nèi)的變量名稱可以相同,例如函數(shù)A可以定義一個(gè)變量a,函數(shù)B也可以定義一個(gè)變量a,這兩個(gè)a變量是完全不同的變量。
比如有個(gè)人叫小明,在同一個(gè)家庭里只會(huì)有一個(gè)小明,而不同的家庭可以有不同的小明(不同的人,但都叫小明),但如果這群小明去到學(xué)校,就必須額外命名以區(qū)分哪個(gè)小明是小明(一個(gè)學(xué)校只會(huì)有一個(gè)小明,其他的可能是小明一號(hào)、小明二號(hào)等)。
默認(rèn)的命名空間
Python默認(rèn)提供三個(gè)命名空間,分別是內(nèi)置的Built-in(Python預(yù)設(shè)的函數(shù)名如abs、char等)、全局Global和局部Local三種。當(dāng)使用變量時(shí),會(huì)從最內(nèi)層(局部命名空間)開始向外層搜索,直到找到對(duì)應(yīng)的名稱為止(如果找不到就會(huì)拋出錯(cuò)誤)。
弄清楚到底使用了哪個(gè)變量
下面這段代碼定義了兩個(gè)變量a,因?yàn)閮蓚€(gè)變量a處于不同的命名空間,所以打印出來(lái)的結(jié)果是不同的。
注意,函數(shù)名也屬于變量名稱,如果將函數(shù)定義為a,就會(huì)覆蓋全局變量a的內(nèi)容。
a = 1 # 定義全局變量a等于1 def hello(): # 定義hello函數(shù) a = 2 # 定義局部變量a等于2 print(a) hello() # 2 print(a) # 1
如果在hello函數(shù)里沒有定義變量a,而是“單純使用變量a”,這時(shí)程序會(huì)先查找hello函數(shù)的命名空間里是否有變量a,如果找不到,就會(huì)向外層尋找,找到之后就會(huì)使用該變量的內(nèi)容。以下例子,執(zhí)行hello函數(shù)后就會(huì)打印出10。
a = 1 def hello(): print(a+9) # 使用全局變量的 a hello() # 10 print(a) # 1
如果將全局變量a移除,執(zhí)行過(guò)程最后就會(huì)發(fā)生錯(cuò)誤,因?yàn)樽詈笠粋€(gè)print(a)是尋找全局變量a,因?yàn)檎也坏剿跃蜁?huì)出錯(cuò)。
def hello(): a = 1 print(a) hello() print(a) # 發(fā)生錯(cuò)誤,因?yàn)檎也坏阶兞?a
同理,如果是不同函數(shù),如果要互相調(diào)用對(duì)方的變量,也會(huì)發(fā)生錯(cuò)誤。
def hello(): a = 1 print(a) def test(): print(a) hello() test() # 發(fā)生錯(cuò)誤,因?yàn)檎也坏阶兞?a
使用global修改全局變量
如果要在函數(shù)里修改全局變量,可以使用「global 全局變量
」的方式。
a = 1 # 定義全局變量 a 等于 1 def hello(): # 定義 hello 函數(shù) global a # 聲明下方的 a 為全局變量 a a = 2 # 修改 a 為 2 print(a) # 1 hello() # 執(zhí)行 hello 函數(shù) print(a) # 2 ( 全局變量 a 被修改為 2 )
全局變量和局部變量容易遇到的陷阱
如果變量的內(nèi)容是列表、字典或集合,在處理“全局變量和局部變量”時(shí),與處理“多個(gè)變量同時(shí)賦值”時(shí)一樣,很容易會(huì)遇到賦值的陷阱,因?yàn)樽兞恐皇?ldquo;標(biāo)簽”,當(dāng)多個(gè)變量同時(shí)指向一個(gè)列表、字典或集合時(shí),只要變量?jī)?nèi)容被修改(并非使用等號(hào)賦值),不論這個(gè)變量是全局還是局部變量,另一個(gè)變量?jī)?nèi)容也會(huì)跟著變動(dòng)。
下面的例子執(zhí)行后,f1函數(shù)的a不受作用域的影響,使用append發(fā)生“改變”后,不論a在何處都會(huì)被影響,連帶b也被影響,但c因?yàn)槭峭ㄟ^(guò)等號(hào)“聲明賦值”,就會(huì)變成“局部變量”,因此在f1函數(shù)作用域之外的c就不會(huì)被影響,d也不會(huì)被影響。不過(guò)如果在f1的開頭加上global c,等同于將c從局部變量提升到全局變量,f2里的c就會(huì)被影響。
a = [] b = a c = [] d = c def f1(): # global c # 如果加上這行,f2 里的 c 就會(huì)被影響 a.append(1) c = [1] print(a) # [1] print(b) # [1] # 被影響 print(c) # [1] print(d) # [] # 不受影響 def f2(): print(a) # [1] # 被影響 print(b) # [1] # 被影響 print(c) # [] # 不受影響,但如果 f1 加上 global c,此處就會(huì)被影響 print(d) # [] # 不受影響 f1() f2()
global() 和 local()
global() 和 local() 是兩個(gè)可以打印出當(dāng)前變量的方法:
- global():返回一個(gè)字典,內(nèi)容是“全局命名空間”的內(nèi)容。
- local():返回一個(gè)字典,內(nèi)容是“局部命名空間”的內(nèi)容。
下方的程序,執(zhí)行 hello 函數(shù)后會(huì)打印出局部命名空間和全局命名空間的內(nèi)容。
a = 1 def hello(): a = 1 print(locals()) print(globals()) hello() print(a)
如果將locals()放到全局命名空間里,則打印出來(lái)的結(jié)果和global()相同。
a = 1 def hello(): a = 1 hello() print(locals()) print(globals())
到此這篇關(guān)于淺析Python中全局變量和局部變量的使用的文章就介紹到這了,更多相關(guān)Python全局變量和局部變量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 用turtle實(shí)現(xiàn)用正方形畫圓的例子
今天小編就為大家分享一篇Python 用turtle實(shí)現(xiàn)用正方形畫圓的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11Python 3.x基于Xml數(shù)據(jù)的Http請(qǐng)求方法
今天小編就為大家分享一篇Python 3.x基于Xml數(shù)據(jù)的Http請(qǐng)求方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12對(duì)python字典過(guò)濾條件的實(shí)例詳解
今天小編就為大家分享一篇對(duì)python字典過(guò)濾條件的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Python最好的日期處理庫(kù)pendulum的使用指南
關(guān)于日期處理,Python?提供了很多的庫(kù),比如標(biāo)準(zhǔn)庫(kù)?datetime、第三方庫(kù)?dateutil、arrow?等等。本文將為大家介紹一個(gè)小編最喜歡的庫(kù)?pendulum,用起來(lái)可以說(shuō)非常的方便,任何對(duì)日期的操作它都能滿足2022-07-07Pytorch?PyG實(shí)現(xiàn)EdgePool圖分類
這篇文章主要為大家介紹了Pytorch?PyG實(shí)現(xiàn)EdgePool圖分類示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Python加載數(shù)據(jù)的5種不同方式(收藏)
這篇文章主要介紹了Python加載數(shù)據(jù)的5種不同方式(收藏),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11python?調(diào)制解調(diào)的實(shí)現(xiàn)
在Python中,可以使用SciPy和NumPy庫(kù)來(lái)處理信號(hào),包括進(jìn)行FM信號(hào)的解調(diào),本文主要介紹了python?調(diào)制解調(diào)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03