对深拷贝和浅拷贝的学习,带有个人理解,不足之处后期学习再补
文章目录
简述
在Python中需要对一个数据对象进行拷贝,如对 a = [1,2,3,[4,5]] 进行拷贝操作,浅拷贝后的对象b在对 b [3] 子List对象进行append添加值后,会出现a中的List子对象也会发生修改。原因在于对于 a 这种List可变数据类型对象嵌套可变数据类型对象,浅拷贝后的 b 外层List是开辟了新的内存空间,但是嵌套的List是对a中原子对象的引用。为了规避这种情况,因此需要进行深拷贝操作。
关键点
-
需要拷贝的对象最外层是否是可变对象(可变对象:
list、dict、set
等,不可变对象:int、str、tuple
) -
需要拷贝的对象是否包含嵌套子对象(list嵌套list、list嵌套tuple和list等诸多情形)
-
区分开辟新的内存和对原对象的引用
浅拷贝
copy.copy()
最外层为不可变对象
不包含嵌套子对象
不开辟新的内存,对原对象的引用。
![Snipaste_2023-04-05_22-24-43](https://raw.githubusercontent.com/whoDDD/MinePicGo/main/images/202304070924606.png)
包含嵌套子对象
不开辟新的内存,最外层是对原对象的引用,子对象也是对原子对象的引用。
最外层为可变对象
不包含嵌套子对象
开辟新的内存,与原对象相互独立。
包含嵌套子对象
最外层可变对象开辟新的内存,嵌套的子对象是对原子对象的引用。
深拷贝
copy.deepcopy()
最外层为不可变对象
不包含嵌套子对象
不开辟新内存,对原对象的引用。
包含嵌套子对象
最外层开辟新内存,子对象为可变对象则开辟新内存,子对象为不可变对象则是对原子对象的引用。
最外层为可变对象
不包含嵌套子对象
开辟新的内存,与原对象相互独立。
包含嵌套子对象
最外层开辟新的内存,子对象为可变对象则开辟新的内存,子对象为不可变对象则是对原子对象的引用。
总结
通过初步的观察可以发现:
- 当最外层为不可变对象时,无论是否有嵌套子对象,浅拷贝都是对原对象的引用。
- 当最外层为可变对象时,不包含嵌套子对象的浅拷贝后是开辟新内存,二者相互独立的;如果包含嵌套子对象则存在对原子对象的引用,使用时需注意。
- 深拷贝时需要特别关注是否存在嵌套子对象,如果不存在,那么对于不可变对象则是对原对象的引用;如果存在,那么对于最外层不可变对象则是开辟新内存。深拷贝时的嵌套子对象都是相同的规则,是可变对象则开辟新内存,是不可变对象则是对原对象的引用。