Python 簡易手冊
單元 52 - global 陳述與 nonlocal 陳述
一般來說,函數 (function) 可以直接使用全域變數 (global variable) ,但是不能修改,因為一旦修改就是指派 (assignment) ,這樣是建立函數內的區域變數 (local variable) ,就變成不是非最外層的全域變數,因此如果要修改全域變數,也就是重新指派全域變數的值,那就要在函數中用關鍵字 (keyword) global 宣告該全域變數,舉例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 定義全域變數 a = 0 # 定義使用全域變數的函數 def do_something(): print(a) # 定義修改全域變數的函數 def do_something2(): global a a = 2 # 呼叫函數 do_something2() do_something() # 檔名: global_demo.py # 說明: 《Python簡易手冊》的範例 # 網址: http://kaiching.org # 作者: Kaiching Chang # 時間: 2024 年 3 月 |
單元 44 - 函數與 return 陳述介紹如何定義函數。
這個例子中, do_something() 直接印出全域變數 a , do_something2() 則是使用關鍵字 global 宣告變數 a ,執行部分先呼叫 do_something2() ,再呼叫 do_something() 結果如下
> python global_demo.py |
2 |
> |
注意上例是不可變的 (immutable) 資料型態,因為涉及指派,所以必須要 global 宣告,如果是可變的 (mutable) 資料型態,例如串列 (list) ,因為不涉及指派,所以可變的全域變數可以自由修改,例如以下將變數 a 改成串列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 建立全域變數 a = [] # 定義使用全域變數的函數 def do_something(): print(a) # 定義修改全域變數的函數 def do_something2(): a.append(2) # 呼叫函數 do_something2() do_something() # 檔名: global_demo2.py # 說明: 《Python簡易手冊》的範例 # 網址: http://kaiching.org # 作者: Kaiching Chang # 時間: 2024 年 3 月 |
單元 39 - 串列介紹串列的用法。
這裡 do_something2() 改成用串列的 append() 方法 (method) 附加元素,執行結果如下
> python global_demo2.py |
[2] |
> |
至於巢狀函數中,函數中定義的函數如果對上層函數的區域變數涉及重新指派,這要用關鍵字 nonlocal 宣告,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # 外層函數 def do_something(): # 定義區域變數 a = 2 # 內層函數 def do_something2(): # 宣告上層區域變數 nonlocal a # 重新設定上層區域變數 a = 0 # 印出變數 a print(a) # 印出變數 a print(a) # 呼叫內層函數 do_something2() # 呼叫外層函數 do_something() # 檔名: global_demo3.py # 說明: 《Python簡易手冊》的範例 # 網址: http://kaiching.org # 作者: Kaiching Chang # 時間: 2024 年 3 月 |
這裡 do_something2() 定義在 do_something() 內, a 是 do_something() 定義的區域變數,而在第 8 行, do_something2() 中用關鍵字 nonlocal 宣告變數 a ,第 10 行進行重新指派
5 6 7 8 9 10 11 12 | # 內層函數 def do_something2(): # 宣告上層區域變數 nonlocal a # 重新設定上層區域變數 a = 0 # 印出變數 a print(a) |
底下未縮排的部分回到 do_something() 的定義範圍,這裡先印出變數 a ,再呼叫 do_something2()
13 14 15 16 | # 印出變數 a print(a) # 呼叫內層函數 do_something2() |
最底下的執行部分則是只有呼叫 do_something() ,結果如下
> python global_demo3.py |
2 0 |
> |
內建函數 globals() 會回傳現在作用域下所有的識別字 (identifier) 的字典 (dictionary) , locals() 則是回傳區域內所有識別字的字典,所謂區域是指縮排範圍。
參考資料
- https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
- https://docs.python.org/3/reference/simple_stmts.html#the-global-statement