博文参考地址:https://blog.csdn.net/qq_20084101/article/details/82925067
最近在撸码的时候发现了一个严重的问题:
a = [1,2] c = a a[0] = 3 print(c) 结果:[3,2]
细心的你,可能已经发现,当我改变的是a[0] 的值时,c的值也跟着改变了
在这里涉及到了一个python的深浅拷贝
1.Phthon中的赋值语句不会创建对象的拷贝,仅仅只是将名称绑定至一个对象,即 a[0] 和 c 是共用一个地址
2.对于不可变对象,通常没有什么差别,即 a = 0
b = a
a = 1 当 a = 1 时,a 和 b 不在公共同一个地址,a会赋予新地址
3.对于处理可变对象或者可变对象的集合时(数组,字典等),就会出现如上的结果
但是我们需要的是 修改创建的拷贝时,不改变原始的对象,则需要深拷贝
这是一些概念(浅拷贝:两人共用同一辆奥迪,深拷贝:每一人拥有一模一样的奥迪,一人一辆)
浅拷贝:
浅拷贝意味着构造一个新的集合对象,然后用原始对象中找到的子对象的引用来填充它。
从本质上讲,浅层的复制只有一层的深度。复制过程不会递归,因此不会创建子对象本身的副本。
深拷贝:
深拷贝使复制过程递归。
这意味着首先构造一个新的集合对象,然后递归地用在原始对象中找到的子对象的副本填充它。
以这种方式复制一个对象,遍历整个对象树,以创建原始对象及其所有子对象的完全独立的克隆。
创建浅拷贝:
list的改变是浅拷贝,因为list只对一层的对象有效,当列表中有子对象,对子对象的修改将影响原始对象和浅拷贝对象
lis = [1,2] new_lis = list(lis) lis[0] = 3 print(lis) print(new_lis) print("---------------------------") li = [[1,2],[3,4]] new_li = list(li) li[0][0] = 3 print(li) print(new_li) 结果: [[3, 2], [3, 4]] [[3, 2], [3, 4]] --------------------------- [3, 2] [1, 2]
创建深拷贝:
创建深拷贝的的实质时,创建一个独立的对象,即两个对象完全对立(以上述的车为例)
在Python的标准库中的copy模块可以创建深拷贝,这个模块为创建任意python对象的浅拷贝和深拷贝提供了一个简单接口
1.使用deepcopy()
import copy li = [[1,2],[3,4]] new_li = copy.deepcopy(li) li[0][0] = 3 print(li) print(new_li) 结果:[[3, 2], [3, 4]] [[1, 2], [3, 4]]
2.使用 copy.copy() 函数可以创建对象的浅拷贝
3.对象可以通过定义特殊的方法 __copy__()
和 __deepcopy__()
来控制如何复制它们。