我们都知道在python中万物皆对象.
而我们知道对象又分为可变对象和不可变对象先通过一段代码来得出一个结论
a = 1
print(a)
b = a
print(b)
# 查看内存地址
print(id(1))
print(id(a))
print(id(b))
print("*" * 30)
a = 2
print(2)
print(b)
print(id(2))
print(id(a))
print(id(b))
print("*" * 30)
结论:
- 执行完这段代码后,我们会发现,给a改完值,它的内存地址就变了.
- 那就意味着:当不可变对象进行赋值时,不会在原内存空间中直接改值,而是重新开辟一块新的空间来保存数据
知道了上面的结论之后,接下来就来讲讲深拷贝与浅拷贝的区别
- 对象拷贝需要使用一个模块 copy
- copy.copy() 这是浅拷贝
- copy.deepcopy() 这是深拷贝
验证不可变对象的深浅拷贝:
import copy
# 不可变对象的深浅拷贝
a = 1
ac = copy.copy(a)
adc = copy.deepcopy(a)
# 验证是否拷贝成功
# 条件:
# 1. 值相同
# 2. 地址不同
print(id(1))
print(id(a))
print(id(adc))
# 验证发现内存地址相同
'''
结论: 对于不可变对象,无论深浅拷贝,都相当于是对象的赋值操作
'''
验证简单的可变对象
import copy
# 2. 简单的可变对象
a = [1, 2, 3, 4, 5]
ac = copy.copy(a)
adc = copy.deepcopy(a)
print(id(a))
print(id(ac))
print(id(adc))
print(a,ac,adc)
print("*" * 30)
a[0] = 111
print(id(a))
print(id(ac))
print(id(adc))
print(a,ac,adc)
print("*" * 30)
'''
对于简单的可变对象,无论深浅拷贝,都可以拷贝成功,并具备数据独立性
'''
执行结果:
结论:
- 对于简单的可变对象,无论深浅拷贝,都可以拷贝成功,并具备数据独立性
验证复杂的可变对象(列表中嵌套列表)
import copy
# 3. 复杂的可变对象
c = [1,2]
a = [3,c]
ac = copy.copy(a)
adc = copy.deepcopy(a)
print(id(a))
print(id(ac))
print(id(adc))
print(a,ac,adc)
print("*" * 30)
# 验证独立性
c[0] = 111
print(id(a))
print(id(ac))
print(id(adc))
print(a,ac,adc)
执行结果:
结论:
- 当复杂的可变对象进行浅拷贝时,只拷贝可变对象的第一层引用,如果原数据中的可变数据发生变化,那么拷贝对象也会随之变化
- 当复杂的可变对象进行深拷贝时,会逐层拷贝可变对象的所有引用,知道所有的数据都是不可变对象引用为止,如果原数据的可变数据发生变化,拷贝对象不会随之发生变化
综上简单做个总结吧:
深拷贝与浅拷贝的区别:
深拷贝:
- 使用copy.deepcopy() 函数
- 可以拷贝对象的多层
- 因为会逐层拷贝引用,所以效率低,但是具备数据独立性
浅拷贝(浅拷贝是默认的拷贝方式比较常用):
- 使用 copy.copy() 函数
- 最多拷贝对象的一层
- 因为拷贝空间少,所以速度快,效率高
记住:
不管是给对象进行深拷贝还是浅拷贝,只要拷贝成功就会开辟新的内存空间存储拷贝的对象。