深、浅拷贝之python copy模块

理解copy并不难,先说概念,后面介绍例

直接赋值深拷贝浅拷贝的区别:
直接赋值:简单地拷贝对象的引用,两个对象的id相同。就是对象的引用(别名),就是给当前内存中的对象增加一个“标签”而已。通过使用内置函数 id() ,可以看出指向内存中同一个对象。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。即浅复制只复制对象本身,没有复制该对象所引用的对象。A shallow copy constructs a new compound object and then (to the extentpossible) inserts references into it to the objects found in the original.
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。即创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。A deep copy constructs a new compound object and then, recursively, insertscopies into it of the objects found in the original.
浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用,所以两者就是一样的结果了。

直接赋值

既不是浅拷贝和深拷贝

a = 3
b = a
b = 4

print(a)
print('a: ', id(a))
print(b)
print('b: ', id(b))

输出:
3
a:  1901135948144
4
b:  1901135948176

对组合对象来说,赋值后两者完全一样,相当于浅copy

a = [1, 2, [3, 4]]
b = a
b[2][0] = 100
b[1] = 22

print(a)
print('a: ', id(a))
print(b)
print('b: ', id(b))

输出:
[1, 22, [100, 4]]
a:  2092121743744
[1, 22, [100, 4]]
b:  2092121743744

浅拷贝shallow copy

这里的例子我理解和上面的组合列表的赋值一样

l1 = [1, 2, [3, 4]]
l2 = copy.copy(l1)  # 或l2 = l1.copy()
print(id(l1))
print(id(l2))
l2[0] = 5     # 浅拷贝只拷贝外层,因此对于l1和l2的外层列表来说,已经是被拷贝后独立的模块了
l2[2][0] = 6  # 由于是浅拷贝,深层没有拷贝到,还属于引用,不是独立的模块
print(l1) 
print(l2)

输出:
2929232665920
2929232653440
[1, 2, [6, 4]]
[5, 2, [6, 4]]

深拷贝deep copy

l1 = [1, 2, [3, 4]]
l2 = copy.deepcopy(l1)
print(id(l1))
print(id(l2))
l2[0] = 5
l2[2][0] = 6
# 注意比较和浅拷贝的区别
print(l1)
print(l2)

输出:
2085595337216
2085595553600
[1, 2, [3, 4]]
[5, 2, [6, 4]]
posted @ 2022-08-18 17:18  胖白白  阅读(45)  评论(0编辑  收藏  举报