python對象
Python 中,一切皆對象。每個對象由:標識(identity)、類型(type)、value(值)組成。
標識用於唯一標識對象,通常應用於對象在計算機內存地址。使用內置函數id(obj)可返回對象obj的標識。
python的傳遞
python中的傳遞是引用傳遞。變量就是對象的引用,變量中存着對象的內存地址。
python是動態語言。變量不需要顯示聲明類型(type),根據變量引用的對象,python解釋器自動確定數據類型。
python是強類型語言,每個對象都有數據類型,並只支持該類型支持的操作。
變量存放在棧中,棧中存放的obj的內存地址。而obj存放在堆中。堆中的這個obj存着:value、type、id(內存地址)。

不可變對象
在不可變對象中,變量和對象是互相獨立的,當新建一個變量指向對象是不會對對象有任何影響。
a = "123" b = a a = "xyz" print (a) print (b)
這個打印結果就是"xyz" "123"。對照上面的內存圖。這就解釋了為什么說python的變量是個標簽。當b=a , a=xyz時,a這個變量就跟標簽一樣就貼在了"xyz"這個對象上(實質上是新的內存地址賦給了a)。由原來"123"有兩個標簽a和b,變成了b指向123,a指向新的對象xyz。這些前提一定要基於對象是不可變對象(strings, tuples, 和numbers)。
可變對象
在可變對象(list,dict,set)中,如果會直接在當前對象進行操作。並不會為新的變量進行副本拷貝。
a = [1, 2, 3] b = a a[0], a[1], a[2] = 4, 5, 6 //改變原來 list 中的元素 >>> a [4, 5, 6] >>> b [4, 5, 6]
淺拷貝和深拷貝
淺拷貝
對於不可變類型,淺復制僅僅對內存地址進行復制,不會開辟新的內存空間。
對於可變類型,淺復制會開辟新的內存空間(僅僅是最頂層開辟了新的空間,里層的元素地址還是一樣的)。子序列中的元素地址還是一樣的(新舊對象子序列是共享的)。
淺拷貝后,改變原始對象中為可變類型的元素的值,會同時影響拷貝對象的;改變原始對象中為不可變類型的元素的值,只有原始類型受影響。
深拷貝
淺拷貝,除了頂層拷貝,還對子元素也進行了拷貝(本質上遞歸淺拷貝)。
經過深拷貝后,原始對象和拷貝對象所有的元素地址都沒有相同的了(對於不可變對象指向相同的地址空間,可變對象序列內存地址就不同了)。
import copy a = [1, 2, 3, 4, ['a', 'b']]#原始對象 b = a #賦值,傳對象的引用 c = copy.copy(a) #對象拷貝,淺拷貝 d = copy.deepcopy(a) #對象拷貝,深拷貝 a.append(5) #修改對象a a[4].append('c') #修改對象a中的['a', 'b']list對象 print ('a = ', a) print ('b = ', b) print ('c = ', c) print ('d = ', d) print(id(a)) print(id(c)) print(id(d))
結果:



