<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 變量的作用域 [TOC] ## 特點 python的作用域是靜態的,在源代碼中變量名被賦值的位置決定了該變量能被訪問的范圍。即Python變量的作用域由變量所在源代碼中的位置決定。Python中并不是所有的語句塊中都會產生作用域。**只有當變量在Module(模塊)、Class(類)、def(函數)中定義的時候,才會有作用域的概念。** **1. 函數內部的變量,函數外部不能訪問** ```python def func(): variable = 100 print(variable) print(variable) # name 'variable' is not defined ``` **2. 函數上層的變量(標量)只能讀取,不能再次定義,初始化** ```python def counter1(): n = 0 def compute(): n = n + 1 # n為標量(數值,字符串,浮點數),Python程序會因為“如果內部函數有引用外部函數的同名變量或者全局變量,并且對這個變量有修改.那么python會認為它是一個局部變量,又因為函數中沒有n的定義和賦值,所以報錯 # y = n + 1 # 更改為y就沒事 # return y return n return compute ``` ```python variable = 300 def test_scopt(): print(variable) # 此時調用局部變量variable并有沒綁定到一個內存對象(沒有定義和初始化,即沒有賦值)。本質上還是遵循的LEGB法則 variable = 200 #因為這里,前面調用過一次,所以variable就變為了局部變量 # print(variable) # 寫在下面就沒問題,因為variable是新的局部變量,而不是重新被定義,卻沒有綁定 test_scopt() ``` Python中的模塊代碼在執行之前,并不會經過預編譯,但是模塊內的函數體代碼在運行前會經過預編譯,因此不管變量名的綁定發生在作用域的那個位置,都能被編譯器知道。Python雖然是一個靜態作用域語言,但變量名查找是動態發生的,直到在程序運行時,才會發現作用域方面的問題, **3. list,dict等復合變量里面的值都可以引用更改** ```python def counter(): n = [0] def compute(): n[0] += 1 # 更改的是n里面的第一個值,不是更改n return n[0] return compute func = counter() func() # 1 func() # 2 func() # 3 ``` **4. global 聲明全局變量,如果在局部要對全局變量修改,需要在局部也要先聲明該全局變量** ```python def counter1(): n = 0 def compute(): global n # 如果在局部要對全局變量修改,需要在局部也要先聲明該全局變量,但此處也會報錯,因為沒有全局變量n n += 1 return n return compute # right def counter1(): global n n = 0 def compute(): global n n += 1 return n return compute ``` **5. nonlocal關鍵字用來在函數或其他作用域中使用外層(非全局)變量** ```python def make_counter(): count = 0 def counter(): nonlocal count # 使用外層非全局變量 count += 1 return count return counter ``` ## 作用域的類型 在Python中,使用一個變量時并不嚴格要求需要預先聲明它,但是在真正使用它之前,它必須被綁定到某個內存對象(被定義、賦值);這種變量名的綁定將在當前作用域中引入新的變量,同時屏蔽外層作用域中的同名變量。 **L(local)局部作用域** 局部變量:包含在def關鍵字定義的語句塊中,即在函數中定義的變量。每當函數被調用時都會創建一個新的局部作用域。Python中也有遞歸,即自己調用自己,每次調用都會創建一個新的局部命名空間。在函數內部的變量聲明,除非特別的聲明為全局變量,否則均默認為局部變量。有些情況需要在函數內部定義全局變量,這時可以使用global關鍵字來聲明變量的作用域為全局。局部變量域就像一個 棧,僅僅是暫時的存在,依賴創建該局部作用域的函數是否處于活動的狀態。所以,一般建議盡量少定義全局變量,因為全局變量在模塊文件運行的過程中會一直存在,占用內存空間。 注意:如果需要在函數內部對全局變量賦值,需要在函數內部通過global語句聲明該變量為全局變量。 **E(enclosing)嵌套作用域** E也包含在def關鍵字中,E和L是相對的,E相對于更上層的函數而言也是L。與L的區別在于,對一個函數而言,L是定義在此函數內部的局部作用域,而E是定義在此函數的上一層父級函數的局部作用域。主要是為了實現Python的閉包,而增加的實現。 **G(global)全局作用域** 即在模塊層次中定義的變量,每一個模塊都是一個全局作用域。也就是說,在模塊文件頂層聲明的變量具有全局作用域,從外部開來,模塊的全局變量就是一個模塊對象的屬性。 注意:全局作用域的作用范圍僅限于單個模塊文件內 **B(built-in)內置作用域** 系統內固定模塊里定義的變量,如預定義在builtin 模塊內的變量。 ## 作用域鏈:變量名解析LEGB法則 搜索變量名的優先級:**局部作用域 > 嵌套作用域 > 全局作用域 > 內置作用域** LEGB法則: 當在函數中使用未確定的變量名時,Python會按照優先級依次搜索4個作用域,以此來確定該變量名的意義。首先搜索局部作用域(L),之后是上一層嵌套結構中def或lambda函數的嵌套作用域(E),之后是全局作用域(G),最后是內置作用域(B)。按這個查找原則,在第一處找到的地方停止。如果沒有找到,則會出發NameError錯誤。 **example 1** ```python name = "lzl" def f1(): print(name) def f2(): name = "eric" f1() f2() # 在函數未執行之前,作用域鏈就已經形成了,此時f1()的上一級應該name = 'lzl' ``` **example 2** ```python def scope_test(): def do_local(): spam = "local spam" # 此函數定義了另外的一個spam字符串變量,并且生命周期只在此函數內。此處的spam和外層的spam是兩個變量,如果寫出spam = spam + “local spam” 會報錯 def do_nonlocal(): nonlocal spam # 使用外層的spam變量 test spam spam = "nonlocal spam" def do_global(): global spam spam = "global spam" spam = "test spam" do_local() print("After local assignmanent:", spam) # test spam do_nonlocal() print("After nonlocal assignment:",spam) # nonlocal spam do_global() print("After global assignment:",spam) # nonlocal spam ???? 先找是本地變量,找到的本地變量已經在do_nonlocal()里面改變了所以輸出的是nonlocal spam scope_test() print("In global scope:",spam) # global spam ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看