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() 直接印出全域變數 ado_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() 內, ado_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() 則是回傳區域內所有識別字的字典,所謂區域是指縮排範圍。

參考資料

上一頁 單元 51 - 產生器運算式
回 Python 簡易手冊 首頁
下一頁 單元 53 - 協程
回 Python 教材首頁
回程式語言教材首頁