python中對象、傳遞與拷貝


python對象

  Python 中,一切皆對象。每個對象由:標識(identity)、類型(type)、value(值)組成。

標識用於唯一標識對象,通常應用於對象在計算機內存地址。使用內置函數id(obj)可返回對象obj的標識。

同時要注意類型是屬於對象的,而不是變量。而對象有兩種,“可更改”(mutable)與“不可更改”(immutable)對象。在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是可以修改的對象。

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

結果:

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM