淺析Python中全局變量和局部變量的使用
什么是全局變量和局部變量?
在Python中,主程序和每個函數都擁有自己的命名空間(namespace)。簡單的區(qū)分規(guī)則如下:
- 主程序定義了“全局”的命名空間,主程序中定義的變量是“全局變量”。
- 每個函數定義了“局部”的命名空間,函數內部定義的變量就是“局部變量”。
- 每個命名空間中的變量名稱都是“唯一的”。不同命名空間內的變量名稱可以相同,例如函數A可以定義一個變量a,函數B也可以定義一個變量a,這兩個a變量是完全不同的變量。
比如有個人叫小明,在同一個家庭里只會有一個小明,而不同的家庭可以有不同的小明(不同的人,但都叫小明),但如果這群小明去到學校,就必須額外命名以區(qū)分哪個小明是小明(一個學校只會有一個小明,其他的可能是小明一號、小明二號等)。
默認的命名空間
Python默認提供三個命名空間,分別是內置的Built-in(Python預設的函數名如abs、char等)、全局Global和局部Local三種。當使用變量時,會從最內層(局部命名空間)開始向外層搜索,直到找到對應的名稱為止(如果找不到就會拋出錯誤)。
弄清楚到底使用了哪個變量
下面這段代碼定義了兩個變量a,因為兩個變量a處于不同的命名空間,所以打印出來的結果是不同的。
注意,函數名也屬于變量名稱,如果將函數定義為a,就會覆蓋全局變量a的內容。
a = 1 # 定義全局變量a等于1 def hello(): # 定義hello函數 a = 2 # 定義局部變量a等于2 print(a) hello() # 2 print(a) # 1
如果在hello函數里沒有定義變量a,而是“單純使用變量a”,這時程序會先查找hello函數的命名空間里是否有變量a,如果找不到,就會向外層尋找,找到之后就會使用該變量的內容。以下例子,執(zhí)行hello函數后就會打印出10。
a = 1 def hello(): print(a+9) # 使用全局變量的 a hello() # 10 print(a) # 1
如果將全局變量a移除,執(zhí)行過程最后就會發(fā)生錯誤,因為最后一個print(a)是尋找全局變量a,因為找不到所以就會出錯。
def hello(): a = 1 print(a) hello() print(a) # 發(fā)生錯誤,因為找不到變量 a
同理,如果是不同函數,如果要互相調用對方的變量,也會發(fā)生錯誤。
def hello(): a = 1 print(a) def test(): print(a) hello() test() # 發(fā)生錯誤,因為找不到變量 a
使用global修改全局變量
如果要在函數里修改全局變量,可以使用「global 全局變量
」的方式。
a = 1 # 定義全局變量 a 等于 1 def hello(): # 定義 hello 函數 global a # 聲明下方的 a 為全局變量 a a = 2 # 修改 a 為 2 print(a) # 1 hello() # 執(zhí)行 hello 函數 print(a) # 2 ( 全局變量 a 被修改為 2 )
全局變量和局部變量容易遇到的陷阱
如果變量的內容是列表、字典或集合,在處理“全局變量和局部變量”時,與處理“多個變量同時賦值”時一樣,很容易會遇到賦值的陷阱,因為變量只是“標簽”,當多個變量同時指向一個列表、字典或集合時,只要變量內容被修改(并非使用等號賦值),不論這個變量是全局還是局部變量,另一個變量內容也會跟著變動。
下面的例子執(zhí)行后,f1函數的a不受作用域的影響,使用append發(fā)生“改變”后,不論a在何處都會被影響,連帶b也被影響,但c因為是通過等號“聲明賦值”,就會變成“局部變量”,因此在f1函數作用域之外的c就不會被影響,d也不會被影響。不過如果在f1的開頭加上global c,等同于將c從局部變量提升到全局變量,f2里的c就會被影響。
a = [] b = a c = [] d = c def f1(): # global c # 如果加上這行,f2 里的 c 就會被影響 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,此處就會被影響 print(d) # [] # 不受影響 f1() f2()
global() 和 local()
global() 和 local() 是兩個可以打印出當前變量的方法:
- global():返回一個字典,內容是“全局命名空間”的內容。
- local():返回一個字典,內容是“局部命名空間”的內容。
下方的程序,執(zhí)行 hello 函數后會打印出局部命名空間和全局命名空間的內容。
a = 1 def hello(): a = 1 print(locals()) print(globals()) hello() print(a)
如果將locals()放到全局命名空間里,則打印出來的結果和global()相同。
a = 1 def hello(): a = 1 hello() print(locals()) print(globals())
到此這篇關于淺析Python中全局變量和局部變量的使用的文章就介紹到這了,更多相關Python全局變量和局部變量內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!