python中變數範圍及嵌套範圍

來源:互聯網
上載者:User
在python中,變數尋找遵循LGB原則,即優先在局部範圍(local scope)中對變數進行尋找,失敗則在全域範圍(global scope)中進行尋找,最後嘗試再內建範圍(build-in scope)內尋找,如果還是未找到的話,則拋出異常。後來由於閉包和嵌套函數的出現,範圍又增加了外部範圍,這樣變數的尋找範圍優先順序變為:局部、外部、全域和內建。 範圍由def、class、lambda等語句產生,if、try、for等語句並不會產生新的範圍。變數名引用分為三個範圍進行尋找:首先是本地,然後是函數內(如果有的話),之後是全域,最後是內建。在預設情況下,變數名賦值會建立或者改變本地變數。全域聲明將會給映射到模組檔案內部的範圍的變數名賦值。Python 的變數名解析機制也稱為 LEGB 法則,具體如下:當在函數中使用未確定的變數名時,Python 搜尋 4 個範圍:本地範圍(L),之後是上一層嵌套結構中 def 或 lambda 的本地範圍(E),之後是全域範圍(G),最後是內建範圍(B)。按這個尋找原則,在第一處找到的地方停止。如果沒有找到,Python 會報錯的。

a = 1def f():      a = 2def g():       print a //[1]:輸出結果為2return gfunc = f()func()//[2]



     代碼的[2]處調用的函數實際上調用的是函數f 中定義的內嵌函數g,在代碼 的[1]處,函數g 內的“print a”的輸出結果為2。初看上去有些疑問,因為函數f 內的約束“a = 2”在其之外應該是不起作用的,當執行func()時,起作用的約束應該是“a = 1”才對。但是我們之前說到了,範圍僅僅是由文本決定的,函數g 位於函數f 之內,所以函數g 定義的範圍內嵌於函數f 的範圍之內。換句話說,函數f 的範圍是函數g 的範圍的直接外圍範圍,所以,按照最內嵌套範圍規則,[1]處的名字引用應該引用的是函數f 定義的範圍中所建立的約束。

儘管在代碼清單8-2 的[2]處,“a = 2”這個約束已經不起作用了,但是Python 在執行“func = f()”時,會執行函數f 中的“def g():”語句,這時Python 會將約束“a = 2”與函數g 對應的函數對象捆綁在一起,將捆綁後的結果返回,這個捆綁起來的整體被稱為“閉包”。

      實際上這裡有一個相當微妙的問題,最內嵌套範圍規則是“閉包”的結果呢,還是“閉包”是最內嵌套範圍規則的實現方案。這兩個問題看上去是一致的,但卻隱含著誰決定誰的關係。實際上,Python 實現閉包是為了實現最內嵌套範圍規則。換句話說,最內嵌套範圍規則是語言設計時的設計策略,即是形而上的“道”;而閉包則實現語言時的一種方案,即是形而下的“器”。

   
python能夠改變變數範圍的程式碼片段是def、class、lamda.    def scopetest():          localvar=6;          print(localvar)              scopetest()      #print(localvar) #去除注釋這裡會報錯,因為localvar是本地變數      if/elif/else、try/except/finally、for/while    while True:          newvar=8          print(newvar)          break;            print(newvar)            try:          newlocal=7          raise Exception      except:          print(newlocal)#可以直接使用哦  輸出結果:8 8 7可見這個關鍵字中定義變數,他們的範圍跟外部是一致的,這個跟Java的範圍概念有點不一樣。    變數搜尋路徑是:本地變數->全域變數    def scopetest():          var=6;          print(var)#                var=5       print(var)      scopetest()      print(var)  輸出結果:5 6 5這裡var 首先搜尋的是本地變數,scopetest()中 var=6相當於自己定義了一個局部變數,賦值為6. 當然如果的確要修改全域變數的值,則需要如下:    def scopetest():          global var           var=6;          print(var)#                var=5       print(var)      scopetest()      print(var)  輸出結果:5 6 6再看一種這種情況:    def scopetest():          var=6;          print(var)#          def innerFunc():              print(var)#look here          innerFunc()                var=5       print(var)      scopetest()      print(var)  輸出結果:5 6 6 5


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.