下例示範變數的範圍規則
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 程式碼的用途是否有誤
張貼留言