Python中的global和nonlocal

來源:互聯網
上載者:User

標籤:逗號   color   print   font   變數   原來   部分   def   對象   

在Python中,一個變數的scope範圍從小到大分成4部分:Local Scope(也可以看成是當前函數形成的scope),Enclosing Scope(簡單來說,就是外層函數形成的scope),Global Scope(就是當前檔案形成的scope),Builtins Scope(簡單來說,就是Python內建的變數位於最頂層的scope)。當Python開始尋找一個非限定的變數名時(像obj.attr中的attr,就是一個被限定的變數名字,它被限定在obj對象中,而普通的變數名就是沒有限定的),總是從當前變數名所處的scope開始,順著前面提到的scope鏈開始往上尋找,一旦尋找到就不會往上再繼續尋找,如果尋找完整個scope鏈還是沒找到,Python會報錯。

 

上面提到的變數名尋找順序,可以簡單的記為LEGB(每一個scope的首字母),而global和nonlocal,可以改變尋找順序。

 

global

在檔案中聲明的變數自動成為global的,而如果想在一個函數裡面聲明一個全域變數,就需要使用global關鍵字:

global var1, var2, ...     # 多個變數用逗號隔開

對於global關鍵字,需要注意以下幾點:

1 當Python看到一個變數由global變數聲明,開始尋找的scope不是從這個變數當前所在的scope開始尋找,而是從Global Scope開始尋找;如果Global Scope沒有找到,就會繼續到Builtins Scope尋找;

2 global關鍵字聲明的對象允許賦值,如果這個變數之前不存在,那麼,這次賦值就是建立了一個全域變數;如果這個變數之前存在,那麼,這次賦值就改變了這個全域變數的值:

def test():    global x    x = 1    # x之前不存在,因此在Global Scope建立了一個全域變數xx = 1def test():    global x    x = 99    # x之前在Global Scope中已經存在,因此這裡是改變x的值

3 只要被global關鍵字聲明的變數,都會成為全域變數,如果該變數原來不是全域變數,也會如此,並且,如果之前Global Scope裡面有同名變數,那麼被global聲明的變數會取代這個同名變數:

x = 99def test():    x = 88    global x    # 這樣做的話Python會產生警告:SyntaxWarning: name ‘x‘ is assigned to before global declaration>>>print(x)           # 一開始訪問的是全域變數x>>>99>>>test()              # 執行test函數之前,原本函數裡面的局部變數x成為了全域變數,並取代原來的全域變數>>>print(x)          # 現在訪問的是取代後的全域變數x,值變為88>>>88# 在看一個例子,加入開始沒有定義全域變數xdef test():    x = 88    global x    # 仍會產生相同的警告>>>test()>>>print(x)   # 列印結果為88!!!>>>88

 

nonlocal

nonlocal是Python 3.X加入進來的關鍵字,Python 2.X中沒有。在Python中,嵌套函數是可以訪問外部函數的變數的(至少在>Python 2.2的版本是這樣的,在Python 2.2之前的版本中,變數的尋找從當前函數開始,然後直接到Global Scope,Builtins Scope,跳過了外層函數),但是卻不可以改變外部函數變數的值,如果確實要改變,就的使用nonlocal變數進行聲明:

nonlocal var1, var2,...   # 只在Python 3.X中支援,多個變數用逗號隔開

對於nonlocal關鍵字,需要注意以下幾點:

1 nonlocal關鍵字只在Python 3.X中支援,Python 2.X沒有這個關鍵字;

2 nonlocal關鍵字只可以在函數內部使用,在其他地方使用會報錯;

3 nonlocal聲明的變數,之前必須已經存在(並且是在外部函數中存在),如果變數不存在就對這個變數賦值,會報錯,這點和global關鍵字不一樣:

# 變數存在於Global Scopex = 99def test():    nonlocal x           # 報錯:SyntaxError: name ‘x‘ is assigned to before nonlocal declaration# 變數存在於當前函數def test():    x = 99    nonlocal x           # 報錯:SyntaxError: name ‘x‘ is assigned to before nonlocal declaration

4 對於nonlocal聲明的變數,只會在外部函數中尋找該變數,不會在Global Scope和Builtins Scope中尋找

Python中的global和nonlocal

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.