下例示範變數的範圍規則
def outer(a):
def inner(a):
a += 1
print("inner a =", a)
a += 1
inner(a)
print("outer a =", a)
a = 12
print("global a =", a)
outer(a)
print("global a =", a)
# 《程式語言教學誌》的範例程式
# http://pydoing.blogspot.com/
# 檔名:scope01.py
# 功能:示範 Python 程式
# 作者:張凱慶
# 時間:西元 2010 年 12 月 執行結果如下

我們在 outer() 函數裡頭另外定義了 inner() 函數, inner() 就只能在 outer() 裡頭被呼叫 (call) 。第 10 行
a = 12
所有函數的最外圍建立變數 a ,屬於這個程式檔案的全域範圍。然後以 a 當成參數傳遞給 outer() ,這時程式執行進到 outer() 裡頭,第 6 行
a += 1
a 遞增 1 ,也就是說 outer() 的參數 a 加上 1 ,現在 outer() 的參數 a 等於 13 ,然後再以 a 當成參數傳遞給 inner() ,程式執行進入 inner() 裡頭,第 3 行
a += 1
inner() 的參數 a 加上 1 ,現在 inner() 的參數 a 等於 14 ,因此我們在印出的第二行看到 inner a = 14 。 inner() 執行完,程式回到 outer() 印出 a ,因此我們在印出的第三行看到 outer a = 13 。 outer() 結束,程式會到全域的執行部份,這時再次印出 a ,因此我們看到 global a = 12 。
變數名稱都是 a ,但此 a 非彼 a 。參數只是函數內拷貝的副本,因此不會影響到範圍外相同名稱的變數。
如果我們想要在函數區塊中使用範圍外的變數,可使用關鍵字 (keyword) 中的 global 及 nonlocal 宣告範圍外的變數名稱。
下例示範在 inner() 使用 global ,當 inner() 將 a 加上 1 之時,最外層全域的 a 也遞增 1
def outer(a):
def inner():
global a
a += 1
print("inner a =", a)
a += 1
inner()
print("outer a =", a)
a = 12
print("global a =", a)
outer(a)
print("global a =", a)
# 《程式語言教學誌》的範例程式
# http://pydoing.blogspot.com/
# 檔名:scope02.py
# 功能:示範 Python 程式
# 作者:張凱慶
# 時間:西元 2010 年 12 月 執行結果如下

下例示範在 inner() 使用 nonlocal ,這時 inner() 裡的 a 是上一層的 a ,也就是 outer() 的 a
def outer(a):
def inner():
nonlocal a
a += 1
print("inner a =", a)
a += 1
inner()
print("outer a =", a)
a = 12
print("global a =", a)
outer(a)
print("global a =", a)
# 《程式語言教學誌》的範例程式
# http://pydoing.blogspot.com/
# 檔名:scope03.py
# 功能:示範 Python 程式
# 作者:張凱慶
# 時間:西元 2010 年 12 月 執行結果如下

| 中英文術語對照 | |
|---|---|
| 函數 | function |
| 變數 | variable |
| 參數 | parameter |
| 區域變數 | local variable |
| 範圍 | scope |
| 區塊 | block |
| 呼叫 | call |
| 關鍵字 | keyword |
參考資料
http://docs.python.org/py3k/tutorial/classes.html
http://docs.python.org/py3k/reference/simple_stmts.html
http://docs.python.org/py3k/tutorial/classes.html
http://docs.python.org/py3k/reference/simple_stmts.html
1 則留言:
版主大大你好:
我練習了你網站上的有關 global 程式碼,有錯誤但跟網站上的程式碼一模一樣
顯示: NameError: name 'a' is not defined
反而是nonlocal顯示沒有問題,想請教版主,這 global 程式碼的用途是否有誤
張貼留言