函數的作用域、global與nonlocal
阿新 • • 發佈:2018-12-22
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