python3 浅拷贝和深拷贝
浅拷贝 copy 就是对引用的拷贝
浅拷贝有三种模式:切片操作、工厂函数和copy模块中的copy函数
深拷贝 deepcopy 就是对对象的资源的拷贝
深拷贝只有一种模式,就是copy模式中的deepcopy函数
1、浅拷贝仅仅是复制容器中元素的地址:
定义一个jack 然后切片copy给kangkang,工厂方式给jane
1 >>>jack = ['jack',['age',20]] 2 3 >>>kangkang = jack[:] 4 5 >>>jane = list(jack) 6 7 >>>print(id(jack),id(kangkang),id(jane)) 8 9 2679958866568 2679952671176 2679976501064 10 11 #从id 来看 ,三者是不同的对象,为kangkang和jane重新定义名称 12 >>>kangkang[0]='kangkang' 13 >>>jane[0] = 'jane' 14 15 >>>print (jack,kangkang,jane) 16 17 ['jack', ['age', 20]] ['kangkang', ['age', 20]] ['jane', ['age', 20]] 18 19 #看起来都一样,然后把jane的age 修改一下 20
21 >>>jane[1][1]=22 22 23 >>>print (jack,kangkang,jane) 24 25 ['jack', ['age', 22]] ['kangkang', ['age', 22]] ['jane', ['age', 22]] 26 27 #然后我们发现 年龄全部发生了改变。 正常逻辑来说,不同的对象这样的结果让人匪夷所思,让我们来看下id值 28 29 30 31 print([id(x) for x in jack]) 32 print([id(x) for x in kangkang]) 33 print([id(x) for x in jane]) 34 35 [2679975860464, 2679958810312] 36 [2679958227632, 2679958810312] 37 [2679975984128, 2679958810312] 38 39 #然后我们发现 jack kangkang 和jane的age元素指向的是同一个元素,修改了一个元素,当然就影响到其他人了。 40 #那为什么修改名称没有影响呢;是因为python中字符串不可修改,所以在重命名的时候,会重新创建kangkang和jane对象替换旧的jack
2、然后我们使用深拷贝的方法进行copy
1 >>>import copy 2 >>>jack = ['jack',['age',20]] 3 >>>kangkang = copy.deepcopy(jack) 4 >>>jane = copy.deepcopy(jack) 5 6 >>>print(jack,kangkang,jane) 7 8 >>> kangkang[0] = 'kangkang' 9 >>> jane[0] = 'jane' 10 >>> print jack, tom, anny 11 ['jack', ['age', '20']] ['kangkang', ['age', '20]] ['jane', ['age', 20]] 12 13 >>>jane[1][1] = 22 14 >>>print(jack,kangkang,jane) 15 16 ['jack', ['age', 20]] ['kangkang', ['age', 20]] ['jane', ['age', 22]] 17 18 >>>print([id(x) for x in jack]) 19 20 >>>print([id(x) for x in kangkang]) 21 22 >>>print([id(x) for x in jane]) 23 #这时候他们之间就没有互相影响了,每个人的元素对应每个id
24 ]
25 [2679975860464, 2679976443976]
[2679975860464, 2679952671176]
[2679975860464, 2679976446664]
内部元素都是指向不同的对象。
所以:
浅拷贝:
1、利用切片操作和工厂list方法拷贝,只是单纯拷贝了最外围的对象本身
内部元素只是拷贝了一个引用
2、创建了一个新的组合对象,这个新对象与原对象共享内存中的子对象
深拷贝:
1、利用copy中的deepcopy方法进行拷贝叫做深拷贝,外围和内部元素都进行了拷贝对象本身
2、创建了一个新的组合对象,同时递归的拷贝所有的子对象,新的组合与原对象没有任何关联。