python中變量在內存中的存儲與地址關係解析、淺度/深度copy、值傳遞、引用傳遞

---恢復內容開始---python

1.變量、地址數據結構

 

變量的實現方式有:引用語義、值語義函數

  python語言中變量的實現方式就是引用語義,在變量裏面保存的是值(對象)的引用(值所在處內存空間的地址)。採用這種方式,變量所需的存儲空間大小一致,由於其中只須要保存一個引用。而有些語言(例如c)採用的不是這種方式,它們把變量直接保存在變量的存儲區裏,這種方式就稱爲值語義。這樣的話,一個整數類型的變量就須要保存一個整數所須要的空間(例如c語言中int類型佔用4個字節大小,所能表示的數的最大值爲2^32,2147483647)。spa

  python中變量與對象的引用關係相似於c語言的指針變量與指針指向值的關係。3d

  在python的數據結構中,對象分爲可變對象不可變對象。基本數據類型如int、float等都是不可變對象。在結構數據類型中,元祖tuple、str是不可變對象,list(列表)、dict(字典)、set(集合)是可變對象,可變對象存儲的元素的引用實際上是沒有改變的,改變的是其引用指向的值。指針

  採用引用語義存儲的只是一個變量的值所在的內存地址,而不是這個變量的值自己。對象

如上所示,變量中存儲的是值的引用,也就是指所在內存空間的地址。blog

 id函數(python的內置函數,用來查看對象的身份,也就是內存地址)內存

  對於給變量賦值時,每一次的賦值都會產生一個新的地址空間,將新內容的地址賦值給變量,可是對於相同的值,地址不發生變化。io

  對複雜的數據類型(列表、元祖、字典),若是添加某一項元素,或者添加幾個元素,不會改變其自己的地址,只會改變其內部元素的地址引用,可是若是對其從新賦值時,就會從新賦予地址覆蓋就地址,這時地址就會發生改變。

  python中相同的值的不一樣對象,至關於內存中對於相同值的對象保存了對份。可是對於不可變數據類型,內存中只能有一個相同值的對象。同時要看是否產生新的對象。

2.淺拷貝和深拷貝

copy.copy():淺拷貝,無論多複雜的數據結構,淺拷貝都只會copy一層。

copy.deepcopy():深拷貝,會徹底複製原變量相關的全部數據,到最後一層(自身包含的全部子列表)。在內存那種生成一套徹底同樣的內容。

  由上圖能夠看出,淺拷貝,只拷貝一層,所以當list_從新賦值之後,淺拷貝後list_2包含的子列表發生了變化,而而深拷貝之後的列表list_3所包含的字列表並無發生改變。深拷貝等於徹底複製並從新開闢新的內存空間,和原列表二者之間互不影響。

3.值傳遞與引用傳遞:

  可變對象爲引用傳遞,不可變對象爲值傳遞。(函數傳值)

值傳遞:被調函數在執行時,首先對收到的參數對象生成一個副本,在執行過程當中,是對參數副本的操做,並不會對原參數產生改變。也就是在堆棧中開闢內存空間存放由主調函數傳進來的實參對應的副本值。特色:函數對收到的參數的任何操做,不會對原參數(實參變量)產生影響。

引用傳遞:當傳遞列表或者字典時,若是改變引用的值,就改變了原始對象。(引用傳遞直接傳的是地址,是對原始對象的直接操做。)

由上圖能夠看出,引用傳遞,函數修改的直接是實參的值。可是,在函數體中不能直接修改整個列表或者字典的值,這樣作,也等於建立實參的副本,並不會對實參自己產生影響。以下圖所示。

 

   

 

 

 

 

 

 

 

  

 

---恢復內容結束---

相關文章
相關標籤/搜索