Python 變量做用域

一、做用域介紹 


python中的做用域分4種狀況: L:local,局部做用域,即函數中定義的變量;
E:enclosing,嵌套的父級函數的局部做用域,即包含此函數的上級函數的局部做用域,但不是全局的;
G:globa,全局變量,就是模塊級別定義的變量; B:built-in,系統固定模塊裏面的變量,好比int, bytearray等。 搜索變量的優先級順序依次是:做用域局部>外層做用域>當前模塊中的全局>python內置做用域,也就是LEGB。python

1web

2閉包

3函數

4ui

5spa

6code

7ci

x = int(2.9)  # int built-in作用域

 

g_count = 0  # globalget

def outer():

    o_count = 1  # enclosing

    def inner():

        i_count = 2  # local

固然,local和enclosing是相對的,enclosing變量相對上層來講也是local。 


二、做用域產生


Python中,只有模塊(module),類(class)以及函數(def、lambda)纔會引入新的做用域,其它的代碼塊(如if、try、for等)是不會引入新的做用域的,以下代碼:

1

2

3

4

if True:

    x = 1;

print(x)

# 1

這個是沒有問題的,if並無引入一個新的做用域,x仍處在當前做用域中,後面代碼可使用。

1

2

3

4

def test():

    x2 = 2

print(x2)

# NameError: name 'x2' is not defined

def、class、lambda是能夠引入新做用域的。 


三、變量的修改 


一個不在局部做用域裏的變量默認是隻讀的,若是試圖爲其綁定一個新的值,python認爲是在當前的局部做用域裏建立一個新的變量,也就是說在當前局部做用域中,若是直接使用外部做用域的變量,那麼這個變量是隻讀的,不能修改,如:

1

2

3

4

5

6

7

count = 10

def outer():

    print(count) 

    count = 100

    print(count)

outer()

#UnboundLocalError: local variable 'count' referenced before assignment


這裏第一個print中,使用到了外部做用域的count,這樣後面count就指外部做用域中的count了,再修改就會報錯。 若是沒使用過這個變量,而直接賦值,會認爲是新定義的變量,此時會覆蓋外部做用域中變量,如:

1

2

3

4

5

6

count = 10

def outer():

    count = 100  

    print(count)

outer()

#100

內部做用域中直接聲明瞭count=100,後面使用count都是內部做用域的了。 


四、global關鍵字 


當內部做用域想修改外部做用域的變量時,就要用到global和nonlocal關鍵字了,當修改的變量是在全局做用域(global做用域)上的,就要使用global先聲明一下,代碼以下:

1

2

3

4

5

6

7

8

9

count = 10

def outer():

    global count

    print(count) 

    count = 100

    print(count)

outer()

#10

#100


五、nonlocal關鍵字 


global關鍵字聲明的變量必須在全局做用域上,不能嵌套做用域上,當要修改嵌套做用域(enclosing做用域,外層非全局做用域)中的變量怎麼辦呢,這時就須要nonlocal關鍵字了

1

2

3

4

5

6

7

8

9

10

11

def outer():

    count = 10

    def inner():

        nonlocal count

        count = 20

        print(count)

    inner()

    print(count)

outer()

#20

#20



六、小結 


(1)變量查找順序:LEGB,做用域局部>外層做用域>當前模塊中的全局>python內置做用域;

(2)只有模塊、類、及函數才能引入新做用域;

(3)對於一個變量,內部做用域先聲明就會覆蓋外部變量,不聲明直接使用,就會使用外部做用域的變量;

(4)內部做用域要修改外部做用域變量的值時,全局變量要使用global關鍵字,嵌套做用域變量要使用nonlocal關鍵字。nonlocal是python3新增的關鍵字,有了這個關鍵字,就能完美的實現閉包了。

相關文章
相關標籤/搜索