25. 深浅拷贝
一、什么是浅拷贝
只对对象的最顶层进行的拷贝称为 浅拷贝。我们可以用 copy 模块中的 copy() 方法实现浅拷贝。
import copy
a = [11, 22, 33]
b = [44, 55, 66]
c = [a, b]
d = copy.copy(c)
print(f"c: {c}")
print(f"d: {d}")
print(f"c == d: {c == d}")
print(f"id(c): {id(c)}")
print(f"id(d): {id(d)}")
print(f"c is d: {c is d}")
print(f"id(c[0]): {id(c[0])}")
print(f"id(d[0]): {id(d[0])}")
c[0][0] = 10
print(c)
print(d)
当使用 copy.copy() 来完成浅拷贝的时候,它其实是需要检查以下拷贝的数据是否是可变。如果是可变类型,则拷贝最顶层。如果是不可变类型,则拷贝其引用。
import copy
a = [11, 22, 33]
b = (11, 22, 33)
c = copy.copy(a)
d = copy.copy(b)
print(id(a), id(c))
print(id(b), id(d))
二、什么是深拷贝
对一个对象的所有层次的拷贝(递归拷贝)称为 深拷贝。我们可以使用 copy 模块中的 deepcopy() 方法实现深拷贝。
import copy
a = [11, 22, 33]
b = [33, 44, 55]
c = [a, b]
d = copy.deepcopy(c)
print(f"c: {c}")
print(f"d: {d}")
print(f"c == d: {c == d}")
print(f"id(c): {id(c)}")
print(f"id(d): {id(d)}")
print(f"c is d: {c is d}")
print(f"id(c[0]): {id(c[0])}")
print(f"id(d[0]): {id(d[0])}")
c[0][0] = 10
print(c)
print(d)
二、其它的拷贝方式
【1】、序列切片
当使用序列切片拷贝的时候是 浅拷贝。
a = [11, 22, 33]
b = [33, 44, 55]
c = [a, b]
d = c[:]
print(f"c: {c}")
print(f"d: {d}")
print(f"c == d: {c == d}")
print(f"id(c): {id(c)}")
print(f"id(d): {id(d)}")
print(f"c is d: {c is d}")
print(f"id(c[0]): {id(c[0])}")
print(f"id(d[0]): {id(d[0])}")
c[0][0] = 10
print(c)
print(d)
【2】、字典的 copy() 方法
字典的 copy() 方法也是 浅拷贝。
p1 = dict(name="Sakura", age=10, pet_phrase=["绝对没问题", "封印解除"])
p2 = p1.copy()
print(f"p1: {p1}")
print(f"p2: {p2}")
print(f"p1 == p2: {p1 == p2}")
print(f"id(p1): {id(p1)}")
print(f"id(p2): {id(p2)}")
print(f"p1 is p2: {p1 is p2}")
print(f"id(p1['pet_phrase']): {id(p1['pet_phrase'])}")
print(f"id(p2['pet_phrase']): {id(p2['pet_phrase'])}")
p1["pet_phrase"].append("变回你原来的样子")
print(f"p1: {p1}")
print(f"p2: {p2}")