---恢復內容開始---
1.變量、地址
變量的實現方式有:引用語義、值語義
python語言中變量的實現方式就是引用語義,在變量里面保存的是值(對象)的引用(值所在處內存空間的地址)。采用這種方式,變量所需的存儲空間大小一致,因為其中只需要保存一個引用。而有些語言(例如c)采用的不是這種方式,它們把變量直接保存在變量的存儲區里,這種方式就稱為值語義。這樣的話,一個整數類型的變量就需要保存一個整數所需要的空間(例如c語言中int類型占用4個字節大小,所能表示的數的最大值為2^32,2147483647)。
python中變量與對象的引用關系類似於c語言的指針變量與指針指向值的關系。
在python的數據結構中,對象分為可變對象和不可變對象。基本數據類型如int、float等都是不可變對象。在結構數據類型中,元祖tuple、str是不可變對象,list(列表)、dict(字典)、set(集合)是可變對象,可變對象存儲的元素的引用其實是沒有改變的,改變的是其引用指向的值。
采用引用語義存儲的只是一個變量的值所在的內存地址,而不是這個變量的值本身。
如上所示,變量中存儲的是值的引用,也就是指所在內存空間的地址。
id函數(python的內置函數,用來查看對象的身份,也就是內存地址)
對於給變量賦值時,每一次的賦值都會產生一個新的地址空間,將新內容的地址賦值給變量,但是對於相同的值,地址不發生變化。
對復雜的數據類型(列表、元祖、字典),如果添加某一項元素,或者添加幾個元素,不會改變其本身的地址,只會改變其內部元素的地址引用,但是如果對其重新賦值時,就會重新賦予地址覆蓋就地址,這時地址就會發生改變。
python中相同的值的不同對象,相當於內存中對於相同值的對象保存了對份。但是對於不可變數據類型,內存中只能有一個相同值的對象。同時要看是否產生新的對象。
2.淺拷貝和深拷貝
copy.copy():淺拷貝,不管多復雜的數據結構,淺拷貝都只會copy一層。
copy.deepcopy():深拷貝,會完全復制原變量相關的所有數據,到最后一層(自身包含的所有子列表)。在內存那種生成一套完全一樣的內容。
由上圖可以看出,淺拷貝,只拷貝一層,因此當list_重新賦值以后,淺拷貝后list_2包含的子列表發生了變化,而而深拷貝以后的列表list_3所包含的字列表並沒有發生改變。深拷貝等於完全復制並重新開辟新的內存空間,和原列表兩者之間互不影響。
3.值傳遞與引用傳遞:
可變對象為引用傳遞,不可變對象為值傳遞。(函數傳值)
值傳遞:被調函數在執行時,首先對收到的參數對象生成一個副本,在執行過程中,是對參數副本的操作,並不會對原參數產生改變。也就是在堆棧中開辟內存空間存放由主調函數傳進來的實參對應的副本值。特點:函數對收到的參數的任何操作,不會對原參數(實參變量)產生影響。
引用傳遞:當傳遞列表或者字典時,如果改變引用的值,就改變了原始對象。(引用傳遞直接傳的是地址,是對原始對象的直接操作。)
由上圖可以看出,引用傳遞,函數修改的直接是實參的值。但是,在函數體中不能直接修改整個列表或者字典的值,這樣做,也等於創建實參的副本,並不會對實參本身產生影響。如下圖所示。
---恢復內容結束---