python中的深拷貝和淺拷貝理解在python中,,對(duì)象賦值實(shí)際上是對(duì)象的引用,。當(dāng)創(chuàng)建一個(gè)對(duì)象,然后把它賦給另一個(gè)變量的時(shí)候,,python并沒有拷貝這個(gè)對(duì)象,,而只是拷貝了這個(gè)對(duì)象的引用。以下分兩個(gè)思路來(lái)分別理解淺拷貝和深拷貝:
1,、利用切片操作和工廠方法list方法拷貝 代碼場(chǎng)景:有一個(gè)小伙jack,,tom通過切片操作拷貝jack,anny通過工廠方法拷貝jack,。 >>> jack = ['jack', ['age', 20]] >>> tom = jack[:] >>> anny = list(jack) 來(lái)看下三者的id值: >>> print id(jack), id(tom), id(anny) 144846988 144977164 144977388 從id值來(lái)看,,三者是不同的對(duì)象。為tom和anny重新命名為各自的名稱: >>> tom[0] = 'tom' >>> anny[0] = 'anny' >>> print jack, tom, anny ['jack', ['age', 20]] ['tom', ['age', 20]] ['anny', ['age', 20]] 從這里來(lái)看一切正常,,可是anny只有18歲,,重新為anny定義歲數(shù)。 >>> anny[1][1] = 18 >>> print jack, tom, anny ['jack', ['age', 18]] ['tom', ['age', 18]] ['anny', ['age', 18]] 這時(shí)候奇怪的事情發(fā)生了,,jack,、tom、anny的歲數(shù)都發(fā)生了改變,,都變成了18了,。jack、tom,、anny他們應(yīng)當(dāng)都是不同的對(duì)象,,怎么會(huì)互相影響呢?看下jack,,tom,,anny的內(nèi)部元素每個(gè)元素id: >>> [id(x) for x in jack] [3073896320L, 3073777580L] >>> [id(x) for x in tom] [144870744, 3073777580L] >>> [id(x) for x in anny] [144977344, 3073777580L] 恍然大悟,原來(lái)jack,、tom,、anny的歲數(shù)元素指向的是同一個(gè)元素。修改了其中一個(gè),,當(dāng)然影響其他人了,。那為什么修改名稱沒影響呢?原來(lái)在 python中字符串不可以修改,,所以在為tom和anny重新命名的時(shí)候,,會(huì)重新創(chuàng)建一個(gè)’tom’和’anny’對(duì)象,,替換舊的’jack’對(duì)象。為 了便于理解,,我畫了一個(gè)草圖: 2,、利用copy中的deepcopy方法進(jìn)行拷貝 為了讓他們之間不互相影響,用deepcopy來(lái)試試 >>> jack = ['jack', ['age', '20']] >>> import copy >>> tom = copy.deepcopy(jack) >>> anny = copy.deepcopy(jack) 根據(jù)第一個(gè)思路進(jìn)行重命名,,重定歲數(shù)操作: >>> tom[0] = 'tom' >>> anny[0] = 'anny' >>> print jack, tom, anny ['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', '20']] >>> anny[1][1] = 18 >>> print jack, tom, anny ['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', 18]] 這時(shí)候他們之間就不會(huì)互相影響了,。打印出每個(gè)人的內(nèi)部元素每個(gè)id: >>> [id(x) for x in jack] [139132064, 3073507244L] >>> [id(x) for x in tom] [139137464, 139132204] >>> [id(x) for x in anny] [139141632, 139157548] 他們的內(nèi)部元素也都指向了不同的對(duì)象。 小結(jié): 思路一:利用切片操作和工廠方法list方法拷貝就叫淺拷貝,,只是拷貝了最外圍的對(duì)象本身,內(nèi)部的元素都只是拷貝了一個(gè)引用而已,。 思路二:利用copy中的deepcopy方法進(jìn)行拷貝就叫做深拷貝,,外圍和內(nèi)部元素都進(jìn)行了拷貝對(duì)象本身,而不是引用,。 但是對(duì)于數(shù)字,,字符串和其他原子類型對(duì)象等,沒有被拷貝的說法,,即便是用深拷貝,,查看id的話也是一樣的,如果對(duì)其重新賦值,,也只是新創(chuàng)建一個(gè)對(duì)象,,替換掉舊的而已。 |
|
來(lái)自: java_laq小館 > 《Python》