<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                通過學習《Python函數值傳遞和引用傳遞》一節我們知道,根據實際參數的類型不同,函數參數的傳遞方式分為值傳遞和引用傳遞(又稱為地址傳遞),Python 底層是如何實現它們的呢?Python 中函數參數由實參傳遞給形參的過程,是由參數傳遞機制來控制的。 本節將圍繞值傳遞和引用傳遞,深度剖析它們的底層實現。 ## Python函數參數的值傳遞機制 Python 函數參數的值傳遞,其本質就是將實際參數值復制一份,將其副本傳給形參。這意味著,采用值傳遞方式的函數中,無論其內部對參數值進行如何修改,都不會影響函數外部的實參。 > 值傳遞的方式,類似于《西游記》里的孫悟空,它復制一個假孫悟空,假孫悟空具有的能力和真孫悟空相同,可除妖或被砍頭。但不管這個假孫悟空遇到什么事,真孫悟空都不會受到任何影響。與此類似,傳入函數的是實際參數值的復制品,不管在函數中對這個復制品如何操作,實際參數值本身不會受到任何影響。 下面程序演示了函數參數進行值傳遞的效果: ``` def swap(a , b) : '''下面代碼實現a、b變量的值交換''' a, b = b, a print("swap函數里,a =", a, " b =", b) a = 6 b = 9 swap(a , b) print("函數外部 a =", a ," b =", b) ``` 運行上面程序,將看到如下運行結果: ``` swap函數里,a = 9? b = 6 函數外部 a = 6? b = 9 ``` 從上面的運行結果來看,在 swap() 函數里,經過交換形參 a 和? b 的值,它們的值分別變成了 9 和 6,但函數外部變量 a 和 b 的值依然是 6 和 9。這也證實了,swap() 函數的參數傳遞機制,采用的是值傳遞,函數內部使用的形參 a 和 b,和實參 a、b 沒有任何關系。 ``` swap() 函數中形參 a 和 b,各自分別是實參 a、b 的復制品。 ``` 如果讀者依舊不是很理解,下面通過示意圖來說明上面程序的執行過程。 上面程序開始定義了 a、b 兩個局部變量,這兩個變量在內存中的存儲示意圖如圖 1 所示。 ![](http://h.yiniuedu.com/239d005165b00d15c369545cf4f9ccb0) 圖 1 主棧區中 a、b 變量存儲示意圖 當程序執行 swap() 函數時,系統進入 swap() 函數,并將主程序中的 a、b 變量作為參數值傳入 swap() 函數,但傳入 swap() 函數的只是 a、b 的副本,而不是 a、b 本身。進入 swap() 函數后,系統中產生了 4 個變量,這 4 個變量在內存中的存儲示意圖如圖 2 所示。 ![](http://h.yiniuedu.com/7f181c083a4815a7cf85b8de17d8cafe) 圖 2 主棧區的變量作為參數值傳入 swap() 函數后存儲示意圖 當在主程序中調用 swap() 函數時,系統分別為主程序和 swap() 函數分配兩塊棧區,用于保存它們的局部變量。將主程序中的 a、b 變量作為參數值傳入 swap() 函數,實際上是在 swap() 函數棧區中重新產生了兩個變量 a、b,并將主程序棧區中 a、b 變量的值分別賦值給 swap() 函數棧區中的 a、b 參數(就是對 swap() 函數的 a、b 兩個變量進行初始化)。此時,系統存在兩個 a 變量、兩個 b 變量,只是存在于不同的棧區中而己。 程序在 swap() 函數中交換 a、b 兩個變量的值,實際上是對圖 2 中灰色區域的 a、b 變量進行交換。交換結束后,輸出 swap() 函數中 a、b 變量的值,可以看到 a 的值為 9,b 的值為 6,此時在內存中的存儲示意圖如圖 3 所示。 ![](http://h.yiniuedu.com/9aeed67fd0d0eb5e6ad9525abff591da) 圖 3 swap() 函數中 a、b 交換之后的存儲示意圖 對比圖 3 與圖 1,可以看到兩個示意圖中主程序棧區中 a、b 的值并未有任何改變,程序改變的只是 swap() 函數棧區中 a、b 的值。這就是值傳遞的實質:當系統開始執行函數時,系統對形參執行初始化,就是把實參變量的值賦給函數的形參變量,在函數中操作的并不是實際的實參變量。 ## Python函數參數的引用傳遞 如果實際參數的數據類型是可變對象(列表、字典),則函數參數的傳遞方式將采用引用傳遞方式。 下面程序示范了引用傳遞參數的效果: ``` def swap(dw): # 下面代碼實現dw的a、b兩個元素的值交換 dw['a'], dw['b'] = dw['b'], dw['a'] print("swap函數里,a =", dw['a'], " b =", dw['b']) dw = {'a': 6, 'b': 9} swap(dw) print("外部 dw 字典中,a =", dw['a']," b =",dw['b']) ``` 運行上面程序,將看到如下運行結果: ``` swap 函數里,a = 9? b = 6 外部 dw 字典中,a = 9? b = 6 ``` 從上面的運行結果來看,在 swap() 函數里,dw 字典的 a、b 兩個元素的值被交換成功。不僅如此,當 swap() 函數執行結束后,主程序中 dw 字典的 a、b 兩個元素的值也被交換了。 注意,這里這很容易造成一種錯覺,讀者可能認為,在此 swap() 函數中,使用 dw 字典,就是外界的 dw 字典本身,而不是他的復制品。這只是一種錯覺,實際上,引用傳遞的底層實現,依舊使用的是值傳遞的方式。下面還是結合示意圖來說明程序的執行過程。 程序開始創建了一個字典對象,并定義了一個 dw 引用變量(其實就是一個指針)指向字典對象,這意味著此時內存中有兩個東西:對象本身和指向該對象的引用變量。此時在系統內存中的存儲示意圖如圖 4 所示: ![](http://h.yiniuedu.com/396a5ef9e80ae4e749420b9051cae2e5) 圖 4 主程序創建了字典對象后存儲示意圖 接下來主程序開始調用 swap() 函數,在調用 swap() 函數時,dw 變量作為參數傳入 swap() 函數,這里依然采用值傳遞方式:把主程序中 dw 變量的值賦給 swap() 函數的 dw 形參,從而完成 swap() 函數的 dw 參數的初始化。值得指出的是,主程序中的 dw 是一個引用變量(也就是一個指針),它保存了字典對象的地址值,當把 dw 的值賦給 swap() 函數的 dw 參數后,就是讓 swap() 函數的 dw 參數也保存這個地址值,即也會引用到同一個字典對象。圖 5 顯示了 dw 字典傳入 swap() 函數后的存儲示意圖。 ![](http://h.yiniuedu.com/db3b703cf40449f2e41df79cc165b05e) 圖 5 dw 字典傳入 swap() 函數后存儲示意圖 從圖 5 來看,這種參數傳遞方式是不折不扣的值傳遞方式,系統一樣復制了dw 的副本傳入 swap() 函數。但由于 dw 只是一個引用變量,因此系統復制的是 dw 變量,并未復制字典本身。 當程序在 swap() 函數中操作 dw 參數時,由于 dw 只是一個引用變量,故實際操作的還是字典對象。此時,不管是操作主程序中的 dw 變量,還是操作 swap() 函數里的 dw 參數,其實操作的都是它們共同引用的字典對象,它們引用的是同一個字典對象。因此,當在 swap() 函數中交換 dw 參數所引用字典對象的 a、b 兩個元素的值后,可以看到在主程序中 dw 變量所引用字典對象的 a、b 兩個元素的值也被交換了。 為了更好地證明主程序中的 dw 和 swap() 函數中的 dw 是兩個變量,在 swap() 函數的最后一行增加如下代碼: ``` #把dw 直接賦值為None,讓它不再指向任何對象 dw = None ``` 運行上面代碼,結果是 swap() 函數中的 dw 變量不再指向任何對象,程序其他地方沒有任何改變。主程序調用 swap() 函數后,再次訪問 dw 變量的 a、b 兩個元素,依然可以輸出 9、6。可見,主程序中的 dw 變量沒有受到任何影響。實際上,當在 swap() 函數中增加“dw =None”代碼后,在內存中的存儲示意圖如圖 6 所示。 ![](http://h.yiniuedu.com/da819ae24bc0bfaba714b4d6d339c234) 圖 6 將 swap() 函數中的 dw 賦值為 None 后存儲示意圖 從圖 6 來看,把 swap() 函數中的 dw 賦值為 None 后,在 swap() 函數中失去了對字典對象的引用,不可再訪問該字典對象。但主程序中的 dw 變量不受任何影響,依然可以引用該字典對象,所以依然可以輸出字典對象的 a、b 元素的值。 通過上面介紹可以得出如下兩個結論: 1. 不管什么類型的參數,在 Python 函數中對參數直接使用“=”符號賦值是沒用的,直接使用“=”符號賦值并不能改變參數。 2. 如果需要讓函數修改某些數據,則可以通過把這些數據包裝成列表、字典等可變對象,然后把列表、字典等可變對象作為參數傳入函數,在函數中通過列表、字典的方法修改它們,這樣才能改變這些數據。
                  <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>

                              哎呀哎呀视频在线观看