python中global 和 nonlocal 的作用域

python引用變量的順序: 當前作用域局部變量->外層作用域變量->當前模塊中的全局變量->python內置變量 。

一 global

global關鍵字用來在函數或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關鍵字。

複製代碼
1 gcount = 0
2 
3 def global_test():
4     gcount+=1
5     print (gcount)
6 global_test()
複製代碼

D:\Python34\python.exe E:/PycharmProjects/Day3/globaltest.py
Traceback (most recent call last):
File "E:/PycharmProjects/Day3/globaltest.py", line 6, in <module>
global_test()
File "E:/PycharmProjects/Day3/globaltest.py", line 4, in global_test
gcount+=1
UnboundLocalError: local variable 'gcount' referenced before assignment

Process finished with exit code 1

第一行定義了一個全局變量,(可以省略global關鍵字)。

在global_test 函數中程序會因爲“如果內部函數有引用外部函數的同名變量或者全局變量,並且對這個變量有修改.那麼python會認爲它是一個局部變量,又因爲函數中沒有gcount的定義和賦值,所以報錯。

 

二、聲明全局變量,如果在局部要對全局變量修改,需要在局部也要先聲明該全局變量:

1
2
3
4
5
6
7
gcount = 0
 
def global_test():
    global  gcount
    gcount+=1
    print (gcount)
global_test()

  如果在函數中聲明 gcount 是全局變量,即可對其進行修改。 正確輸出 1 。

 

三、 在局部如果不聲明全局變量,並且不修改全局變量。則可以正常使用全局變量:

1
2
3
4
5
gcount = 0
 
def global_test():
    print (gcount)
global_test()

  如果在局部不修改全局變量,程序正確輸出 0 。

 

四、nonlocal關鍵字用來在函數或其他作用域中使用外層(非全局)變量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def make_counter(): 
    count = 0 
    def counter(): 
        nonlocal count 
        count += 1 
        return count 
    return counter 
       
def make_counter_test(): 
  mc = make_counter() 
  print(mc())
  print(mc())
  print(mc())
 
make_counter_test()

  輸出:

   1

   2

   3

五、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def scope_test():
    def do_local():
        spam = "local spam" #此函數定義了另外的一個spam字符串變量,並且生命週期只在此函數內。此處的spam和外層的spam是兩個變量,如果寫出spam = spam + “local spam” 會報錯
    def do_nonlocal():
        nonlocal  spam        #使用外層的spam變量
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignmane:", spam)
    do_nonlocal()
    print("After nonlocal assignment:",spam)
    do_global()
    print("After global assignment:",spam)
 
scope_test()
print("In global scope:",spam)

  輸出是:

After local assignmane: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

 

 

在函數 add_b 內 global 定義的變量 b,只能在 函數 do_global 內引用, 如果要在 do_global 內修改,必須在 do_global 函數裏面聲明 global  b ,表明是修改外面的 全局變量 b :

複製代碼
def add_b():
    global  b
    b = 42
    def do_global():
        global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()
複製代碼

 

global 定義的變量,表明其作用域在局部以外,即局部函數執行完之後,不銷燬 函數內部以global定義的變量:

def add_a():
    global  a
    a =   3
add_a()
print(a)   

輸出 3 。

 

 

 

 

 

 

 

複製代碼
def add_b():
    global  b
    b = 42
    def do_global():
        global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()
print(b)
複製代碼

以上代碼輸出:

52

52

52

 

複製代碼
def add_b():
    global  b
    b = 42
    def do_global():
        #global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()
複製代碼

以上代碼報錯:

Traceback (most recent call last):
File "E:/PycharmProjects/OOP/exe1.py", line 42, in <module>
add_b()
File "E:/PycharmProjects/OOP/exe1.py", line 40, in add_b
do_global()
File "E:/PycharmProjects/OOP/exe1.py", line 38, in do_global
b = b + 10
UnboundLocalError: local variable 'b' referenced before assignment

原因: global 定義的 b ,只能引用,不能修改。

 

複製代碼
def add_b():
    global  b
    b = 42
    def do_global():
        global  a
        a = b + 10
        print(b)
    do_global()
    print(a)
add_b()
print("a = %s , b = %s " %(a, b))
複製代碼

輸出:

42
52
a = 52 , b = 42

 

 

 

複製代碼
def add_b():
    #global  b
    b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    print(b)
add_b()
print(" b = %s " % b)
複製代碼

以上代碼輸出:

10
42
b = 10

 

 

複製代碼
def add_b():
    #global  b
    b = 42
    def do_global():
        nonlocal  b
        b =  10
        print(b)
    do_global()
    print(b)
add_b()
複製代碼

以上代碼輸出:

10

10

 

 

1
2
3
4
5
6
7
8
9
10
11
def add_b():
    #global  b
    = 42
    def do_global():
        nonlocal  b
        =  10
        print(b)
    do_global()
    print(b)
add_b()
print(" b = %s " % b)

  以上代碼報錯:

print(" b = %s " % b)
NameError: name 'b' is not defined

說明: nonlocal  適用於在局部函數 中 的局部函數, 把最內層的局部 變量設置成外層局部可用,但是還不是全局的。

 

複製代碼
def add_b():
    #global  b
    #b = 42
    def do_global():
        nonlocal  b
        b =  10
        print(b)
    do_global()
    #print(b)
add_b()
複製代碼

以上代碼報錯:

File "E:/PycharmProjects/OOP/exe1.py", line 37
nonlocal b
SyntaxError: no binding for nonlocal 'b' found

nonlocal 要綁定一個局部變量。

 

 

 

複製代碼
def add_b():
    #global  b
    #b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    print(b)
add_b()
print(" b = %s " % b)
複製代碼

以上代碼輸出:

10
10
b = 10

 

 

 

複製代碼
def add_b():
    #global  b
    #b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    #b  = b + 20
    print(b)
add_b()
b = b + 30
print(" b = %s " % b)
複製代碼

以上代碼輸出:

10
10
b = 40

 

複製代碼
def add_b():
    #global  b
    #b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    b  = b + 20
    print(b)
add_b()
b = b + 30
print(" b = %s " % b)
複製代碼

以上代碼報錯:

b = b + 20
UnboundLocalError: local variable 'b' referenced before assignment

 

 

複製代碼
def add_b():
    #global  b
    b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    b  = b + 5
    print(b)
add_b()
b = b + 30
print(" b = %s " % b)
複製代碼

以上代碼輸出:

10
47
b = 40

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章