1. 程式人生 > >函數的作用域、global與nonlocal

函數的作用域、global與nonlocal

oba oca 因此 京東 修改 span 使用 bsp 影響

global

表示不再使用局部局部作用域中的內容,而是改用全局作用域中的變量

 1 a = 100
 2 
 3 
 4 def func():
 5     global a   # 表示不再局部創建這個變量,而是直接使用這個全局的a
 6     a = 28
 7     print(a)   
 8 
 9 
10 func()
11 print(a)    

執行結果

28
28

Process finished with exit code 0

對於可變的數據類型如列表、字典等也可以使用global

 1 lst = [1, 2, 3]
 2 dic = {1: 1, 2: 2}
3 4 5 def func(): 6 global lst 7 global dic 8 lst = [2, 3, 4] 9 dic = {1: 10, 2: 20} 10 print(lst) 11 print(dic) 12 13 14 func() 15 print(lst) 16 print(dic)

執行結果

[2, 3, 4]
{1: 10, 2: 20}
[2, 3, 4]
{1: 10, 2: 20}

Process finished with exit code 0

對於可變數據類型,如果不加global,那麽可以追加元素,刪除元素,修改元素,但是不能直接賦值(就是不能 lst =[....]),直接賦值的結果是創建一個局部的列表或字典

 1 lst = ["麻花疼", "劉強東", "雷軍軍"]
 2 dic = {"馬雲": "淘寶"}
 3 
 4 
 5 def func():
 6     lst.append("馬雲雲")
 7     # lst = ["馬化騰", "雷軍"]
 8     lst.remove("劉強東")
 9     dic["強東"] = "京東"
10     dic["馬雲"] = "支付寶"
11     print(lst)
12     print(dic)
13 
14 
15 func()
16 print(lst)
17 print(dic)

執行結果

[麻花疼
, 雷軍軍, 馬雲雲] {馬雲: 支付寶, 強東: 京東} [麻花疼, 雷軍軍, 馬雲雲] {馬雲: 支付寶, 強東: 京東} Process finished with exit code 0

如果在函數裏面直接賦值,結果會是怎麽樣的呢,來看代碼

 1 lst = ["麻花疼", "劉強東", "雷軍軍"]
 2 dic = {"馬雲": "淘寶"}
 3 
 4 
 5 def func():
 6     # lst.append("馬雲雲")
 7     lst = ["馬化騰", "雷軍"]
 8     # lst.remove("劉強東")
 9     dic["強東"] = "京東"
10     # dic["馬雲"] = "支付寶"
11     print(lst)
12     print(dic)
13 
14 
15 func()
16 print(lst)
17 print(dic)

執行結果

[馬化騰, 雷軍]
{馬雲: 淘寶, 強東: 京東}
[麻花疼, 劉強東, 雷軍軍]
{馬雲: 淘寶, 強東: 京東}

Process finished with exit code 0

nonlocal

nonlocal表示在局部作用域內,調用父級命名空間中的變量

 1 a = 10
 2 
 3 
 4 def func1():
 5     a = 20  # 局部變量
 6 
 7     def func2():
 8         # nonlocal a    # 調用func1裏面的a(值為20)
 9         a = 30        # 將func1裏面a的值改為30
10         print(a)      # 打印30
11 
12     func2()
13     print(a)     # func1裏面a的值已經改為30了,因此打印30,不加nonlocal打印20
14 
15 
16 func1()
17 print(a)    # 打印全局變量a(值為10)

執行結果

30
30
10

Process finished with exit code 0

綜合運用

來看一段代碼

a = 1


def func1():
    a = 2

    def func2():
        nonlocal a    
        a = 3       

        def func3():
            a = 4    
            print(a)    
        print(a)     
        func3()
        print(a)    
    print(a)        
    func2()
    print(a)     


print(a)    
func1()
print(a)   

運行結果

1
2
3
4
3
3
1

Process finished with exit code 0

來看分析,註意執行順序,從上往下,遇到函數定義跳過,遇到函數調用時跳轉到函數定義,定義完接著之前的位置執行。

a = 1      # 創建全局變量a(值為1)


def func1():
    a = 2      # 創建局部變量a

    def func2():
        nonlocal a    # 調用func1(父級命名空間)裏面的a
        a = 3       # 把func1裏面a的值改為3

        def func3():
            a = 4    # 創建局部變量a
            print(a)    # 打印func3裏面局部變量a的值4-----4
        print(a)     # 打印func2裏面的a的值3------3
        func3()
        print(a)    # 打印func2裏面的a的值3(func3裏面的a不影響func2的a)------5
    print(a)        # 打印func1裏的局部變量a的值2------2
    func2()
    print(a)     # 打印func1裏面的a的值3(func1裏面的a已經被func2改成了3)-------6


print(a)    # 打印全局變量a的值1------------1
func1()    # 跳轉到func1定義的位置
print(a)   # 打印1---------7

總結

(1)調用變量是要搞清楚變量是全局變量還是局部變量,如果是局部變量的話是屬於哪個函數的,它能否被其子函數調用

(2)註意代碼的執行順序,代碼從上往下執行,遇到函數定義跳過,等到遇到函數調用時才跳轉到定義的部分開始執行,執行完了後再跳轉到函數調用的地方

函數的作用域、global與nonlocal