Python 入門 10 —— 變量的作用域:global、nonlocal

一般地,將在函數外定義的變量稱爲:外部變量(全局變量);在函數內定義的變量稱爲:內部變量(局部變量)。

global 用法普遍;nonlocal 僅在內嵌函數中使用。

一、關鍵詞 global
1、內部變量僅可在函數內使用,函數結束時自行銷燬,在函數外無法訪問。例如:

def fun(x,y): z = 18; print(x,y,z)		# 內部變量 z 
fun(11,12)    # 11 12 18

print(z)    # z 是內部變量,在函數外不能訪問:NameError: name 'x' is not defined

2、如果要使內部變量變成全局變量,以便在函數外使用,必須用關鍵詞 “global” 聲明一下。這裏要注意的是,聲明語句必須是單獨成句,不能把聲明與賦值放在同一句中,否則會報錯。例如:

def fun(x,y): global z; z= 18; print(x,y,z)
fun(11,12)    # 11 12 18

print(z)     # z 在用“global” 聲明之後成了全局變量:18

3、外部變量在函數內可以訪問,但不可以修改。如果要修改,必須用“global”聲明一下。如果一個內部變量與外部變量同名,則在函數內,外部變量會被暫時隱藏(屏蔽)

a= 16
def fun(x,y,z): print(x,y,z,a)    # a 是外部變量,在函數內可以訪問
fun(11,12,13)    # 11 12 13 16

a= 16
def fun(x,y,z): global a; a= 18; print(x,y,z,a)
fun(11,12,13)    # 11 12 13 18
print(a)    # 外部變量a 在函數內被修改:18

a= 16
def fun(x,y,z): a= 18; print(x,y,z,a)    # a 是外部變量,可以訪問
fun(11,12,13)    # 11 12 13 18
print(a)    # 外部變量a 在函數內只是被暫時隱藏,沒有被修改:16

二、nonlocal
nonlocal 的問題是函數嵌套引起的。如果沒有函數嵌套,將所有變量分爲外部變量(全局變量)和內部變量(局部變量)就夠了。有了函數嵌套,問題就變得複雜了。例如:

def fun01(x):
    a = 11
    def fun02(y):print(y,a)
    fun02(x)

fun01(10)    # 10 11
print(a)    # NameError: name 'a' is not defined

在 fun01() 內部又定義了一個函數fun02()。在fun01()看來,變量 a 肯定是內部變量。但在fun02()看來,a 不是內部變量,也不是全局變量,稱之爲“中間變量”比較合適。按照上述第一部分的規則:在fun02()中引用a,是可以的,但要修改 a 就要加上 global 聲明。例如:

def fun01(x):
    a = 11
    def fun02(y):global a; a =12; print(y,a)
    fun02(x)

fun01(10)    # 10 12
print(a)    # 變量 a 這時成了全局變量:12

問題是,如果在fun02()中想修改 a,但又不想使它成爲全局變量,以確保 a 在 fun01() 結束後自動銷燬,該如何辦呢?答案是:使用 nonlocal 關鍵詞聲明 a 。

def fun01(x):
    a = 11
    def fun02(y):nonlocal a; a =12; print(y,a)
    fun02(x)

fun01(10)    # 10 12
print(a)    # a 在 fun01() 結束後被自動銷燬:NameError: name 'a' is not defined

由上可見,nonlocal關鍵詞僅在內嵌函數內使用。它用於聲明:被聲明的變量是引用自上一層的函數。對比 global 用於聲明:被聲明的變量是引用自自全局變量,二者的用法是很有相似之處的。

global 還可以在函數內用於聲明一個新的變量爲全局變量,那 nonlocal 是否可以在內嵌函數內用於聲明一個新的變量爲“僅可以在上一層函數使用的變量”呢?不可以。用 nonlocal 聲明的變量如果在上一層的函數中不存在,則會報錯。例如:

def fun01(x):
    a = 11
    def fun02(y):nonlocal a; nonlocal b; a =12; print(y,a,b)
    fun02(x)

 # 因爲變量 b 在fun01()中沒有被定義,所以會報語法錯誤: 在SyntaxError: no binding for nonlocal 'b' found

———————————————— 本篇完 ————————————————

看完之後,麻煩您順手點擊下方 “點贊” 兩個字給我點個贊吧 ^-^ , 謝謝您了。

如果您還能像我小學一年級班主任好老師那樣,給我隨心寫上幾句表揚或批評的話語,那真是感激不盡!

在我人生的道路上,有了您的鼓勵和指導,我一定成長快快。

發佈了30 篇原創文章 · 獲贊 6 · 訪問量 3588
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章