學習記錄-Python的局部變數和全局變數
1 定義
- 在被調用函數內賦值的變數是局部變數
- 在所有函數之外賦值的變數是局部變數
當一個函數被調用的時候,就會創建一個局部作用域,在這個函數內的所有變數都存在於該局部作用域內(global的變數除外),該函數返回時,這個局部作用域被銷毀,這個局部作用域內的局部變數隨之丟失
2 作用域的重要性
- 全局作用域中的程式碼不能使用任何局部變數
- 局部作用域中的程式碼可以訪問全局變數
- 一個函數的局部作用域中的程式碼,不能使用其他局部作用域中的變數
- 在不同的作用域中,可以使用相同的名字命名不同的變數
下面根據具體程式碼舉例說明
2.1 全局作用域中的程式碼不能使用任何局部變數
def spam():
egg = 'this is in function spam'
spam()
print(egg)
在函數spam()
(局部作用域)中給egg賦值,然後在全局作用域中調用函數spam()
運行後顯示,egg未被定義
egg是局部變數,而print(egg)
中的變數egg是全局變數,全局作用域中的程式碼不能使用局部作用域中的變數
這一點我理解為:在調用子函數spam()
時,創建了一個局部作用域,並在局部作用域中定義了一個局部變數,當子函數調用結束後,局部作用域和內部定義的局部變數一起沒銷毀,因此在全局作用域中,找不到egg這個局部變數
2.2 局部作用域中的程式碼可以訪問全局變數
def spam():
print(egg)
egg = 'Outside the function'
spam()
全局變數在聲明或賦值時被創建,直到程式被終止或執行結束
如果在egg賦值前調用函數
def spam():
print(egg)
spam()
egg = 'Outside the function'
這時候會顯示變數未被定義
2.3 不同局部作用域中的變數不能相互調用
def spam():
print(egg)
def init():
egg = 'this is in init funcion'
init()
spam()
2.4 在不同的作用域中,可以使用相同的名字命名不同的變數
def spam():
egg = 'this is in spam function'
print(egg)
def init():
egg = 'this is in init funcion'
print(egg)
#egg = 'Out side function'
#print(egg)
init()
spam()
兩個子函數中都定義了變數egg,但在列印時,互不影響
3 全局變數與局部變數同名
在上面說到,可以在局部作用域中調用全局變數,並且在給出的例子中,我們的子函數中只有一個print操作,但如果一個變數既在全局作用域中定義,又在局部作用域中定義,那麼會出現什麼樣的列印結果
def spam():
egg = 'this is in spam function'
print(egg)
def init():
egg = 'this is in init funcion'
print(egg)
egg = 'Out side function'
print(egg)
init()
spam()
這裡我的理解是:在局部作用域要對一個變數進行操作,Python會先在當前局部作用域查找有沒有聲明這個變數,如果有,就優先使用當前局部作用域中的變數,如果當前局部作用域作用域中沒有,才會去全局作用域中尋找
4 global
global允許在局部作用域中聲明全局變數
def spam():
global egg
egg = 'In spam function'
spam()
print(egg)
通過使用global語句在局部作用域中聲明了一個全局變數egg,當函數spam()
調用結束後變數egg並未隨之銷毀
5 全局變數和局部變數的優先順序
在上面的例子中說過,如果在全局變數和局部變數同名,那麼局部作用域中會優先處理在當前作用域中聲明的的變數
用下面的例子進一步說明這個問題
def spam():
print(egg)
egg = 'In spam function'
egg = 'Out side function'
spam()
報錯顯示局部變數在賦值前被引用
,就像前面所說,當在局部作用域中處理一個變數時,Python會先查看這個變數是否在局部作用域中進行聲明,然後在會在全局作用域中查找這個變數的聲明
參考內容
《Python編程快速上手》