Python 中的浅复制和深复制
码农都知道,在面向对象中,对象的复制有深浅之分。在 Python 中,一切皆对象,无论你把对象作为参数传递还是作为返回值,传递的都是引用,也就是浅复制。那么,深复制呢?
在标准库中,copy 模块有两个方法,分别是 copy 和 deepcopy。以 list 对象举例:
in[0]:
import copy
list1 = [1, 2, 3]
new_list1 = list1
new_list2 = copy.copy(list1)
new_list3 = copy.deepcopy(list1)
print list1
print new_list1
print new_list2
print new_list3
执行以上操作,输出为:
out[0]:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
在上例中,list1 和 new_list1 实际指向同一对象,证据如下:
in[1]:
list1[0] = 4
print list1
print new_list1
print new_list2
print new_list3
out[1]:
[4, 2, 3]
[4, 2, 3]
[1, 2, 3]
[1, 2, 3]
那 copy 和 deepcopy 的区别在哪儿?继续看例子
in[2]:
import copy
list1 = [[1, 2], [3, 4], [5, 6]]
new_list1 = copy.copy(list1)
new_list2 = copy.deepcopy(list1)
print list1
print new_list1
print new_list2
list1[0].append(8)
print list1
print new_list1
print new_list2
out[2]:
[[1, 2], [3, 4], [5, 6]]
[[1, 2], [3, 4], [5, 6]]
[[1, 2], [3, 4], [5, 6]]
[[1, 2, 8], [3, 4], [5, 6]]
[[1, 2, 8], [3, 4], [5, 6]]
[[1, 2], [3, 4], [5, 6]]
由上例可见 new_list1 和 new_list2 的引用已经不同于但是其属性的引用就不同了,使用 copy 方法复制出的 new_list1 的属性 new_list[0] 仍然同 list1 共享引用,而使用 deepcopy 方法复制出的 new_list2 副本则不是。
也就是说,如果你想把对象中的属性也被复制,就得使用 deepcopy 方法。