一、赋值
1、在python中,对象的赋值就是简单的引用,a = [1,2,3], b=a,在上述情况下,a和b是一样的,他们指向同一片内存,b不过是a的别名,是引用,我们可以使用b is a去判断,返回True,表名他们地址相同内容也相同,也可以使用id()函数来查看.看两个列表地址是否相同。
2、赋值操作(包括对象作为参数、返回值),不会开辟新的内存空间,他只是赋值了对象的引用.也就是除了b这个名字之外,没有其他的内存开销,修改了a也就影响了b,修改了b,也就影响了a。
浅拷贝会创建新的对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。
浅拷贝有三种形式:
切片操作
:b = a[:]或者b = [x for x in a]
工厂函数
:b = list(a);
copy函数
:b = copy.copy(a)
浅拷贝产生的列表b不再是列表a了,使用is判断可以发现他们不是同一个对象,使用id查看,他们也不指向同一片内存空间,但是当我们使用id(x)for x in a 和id(x) for x in b 来查看a和b中元素地址时,可以看到二者包含的元素的地址时相同的。
在这种情况下列表a 和列表b是不同的对象,修改b理论上不会影响到列表a。
但是要注意的是浅拷贝之所以只拷贝了一层,在列表a中有一个嵌套的list,如果我们修改了它,情况就不一样了,比如:a[3].append(“4”),查看列表b也发生了变化,这是因为我们修改了嵌套的list,修改外层元素,会修改它的引用,让他指向别的位置,修改嵌套列表中的元素,地址未发生变化,指向的都是用一个位置。
三、深拷贝(deepcopy)
深拷贝只是一种形式,copy模块中的deepcoopy()函数,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素,因此他的时间和空间开销要高。
同样的对列表a,如果使用b= copy.deepcopy(a),再修改列表b也不会影响到列表a,即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的联系。
四、拷贝的注意点