python3的local, global, nonlocal簡析
python3:變數作用域及global,nonlocal的用法
在Python程式中宣告、改變、查詢變數名時,都是在一個儲存變數名的名稱空間中進行中,此名稱空間亦稱為變數的作用域。python的作用域是靜態的,在程式碼中變數名被賦值的位置決定了該變數能被訪問的範圍。即Python變數的作用域由變數所在原始碼中的位置決定.
變數作用域之LENGB
L = Local 區域性作用域
E = Enclosing 巢狀作用域
N = nonlocal 只作用於巢狀作用域,而且只是作用在函式裡面
G = global 全域性作用域
B = Built-in 內建作用域
python引用變數的順序: 當前作用域區域性變數->外層作用域變數->當前模組中的全域性變數->python內建變數.
下面講分別舉例說明:
1. L = Local 區域性作用域
區域性變數包含在def定義的函式體內。在函式體內宣告的變數,預設都是區域性變數,除非有特別說明,如全域性變數的宣告要用關鍵字global.
def testlocal():
x = 123 # x即為區域性變數
print(x)
以上程式碼執行就會報NameError, 因為x是個區域性變數,在函式外要print(x), 按照上面python引用變數的順序,是找不了x變數的,故為報錯.
NameError: name 'x' is not defined
1.1 再舉一例:
x = 123 def testlocal(): print(x) testlocal()
以上程式碼執行結果為123, 因為按照上面python引用變數的順序,是找不到x變數的,故會向外層作用域找,就會找到x=123
1.2 如果將程式碼改為:
x = 123
def testlocal():
print(x)
x = 100
testlocal()
這時以上程式碼執行就會報錯.
UnboundLocalError: local variable 'x' referenced before assignment
什麼原因?新手常會遇到這類問題, 因為按照python引用變數的順序,當print(x)時,就會先在函式體內查詢x,能找到,但在他的下一行,故為在宣告前被引用是不對的.
2. G = global 全域性作用域
全域性作用域的變數怎麼用呢?
先看例項:
x = 123
def testGlobal():
print(x)
x = 100
testGlobal()
這就是上面1.2的例項,會報錯,如果將其為:
x = 123
def testGlobal():
global x
print(x)
x = 100
testGlobal()
試試看,結果執行結果為123, 是不會報錯的,自已體會一下吧.
3. nonlocal的用法
這個一般是用在閉包函式裡. 例項如下:
x = 123
def outer():
x = 100
def inter():
x = 200
inter()
print(x)
func()
執行的結果為100, 那如果要求inter中對x的修改是有效的,必須加上關鍵字nonlocal
x = 123
def outer():
x = 100
def inter():
nonlocal x
x = 200
inter()
print(x)
func()
執行的結果為200, 符合預期.
4. 其它.
python變數的作用域只在作用域內有效,需要注意的是,在if-elif-else, for-in, while, try-except-finally這些關鍵字中並不會產生特定的作用域,如下:
#!/user/bin/python3
#-*- coding:utf-8 -*-
for i in range(10):
i = i + 1
print(i)
>>>10
執行結果並不會報錯,會輸入i, 這裡的i就是一個全域性變數,這是python的一個特點,如果在C/java中這種寫法就會報錯,會報變數i會宣告.