一 赋值
Python中,对象的赋值就是简单的对象引用
示例:
如上,a和b是一样的,指向同一片内存地址,b只是a的别名,是引用。我们可以通过 is或id()去判断两个列表的地址是否相同。
赋值操作(包括对象作为参数,返回值)不会开辟新的内存空间,只是复制对象的引用。
二 浅拷贝
浅拷贝会创建新的对象,其内容非原对象的引用,而是原对象内第一层对象的引用。
浅拷贝有三种形式: 切片操作,工厂函数,copy模块中的copy函数
示例:
a = [2,"test", ["1","python"]]
切片:b = a[:] 或者 b = [x for x in a]
工厂函数: b = list(a)
copy函数:b = copy.copy(a)
此时a 和 b已经是完全不同的对象。指向的引用地址也不相同。但是通过id(x) for x in a 和 id(x) for x in b 来查看 a和b中元素的地址,可以发现包含的元素地址是相同的。
但是需要注意的一点是,浅拷贝只是拷贝了一层,在列表a中有一个嵌套的list。如果我们修改了它,情况就不一样了。
如图所示,修改a的同时,b也发生了变化。这是因为我们修改了嵌套的list。修改外层元素,会修改它的引用地址。但是修改嵌套列表中的元素列表的地址未发生变化,指向的都是同一个地址。
三 深拷贝
深拷贝只有一种形式,copy模块中的deepcopy()函数。
深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的空间开销要高。
同样对于列表a。 如果使用 b =copy.deepcopy(a)。再修改b不会影响a,因为深拷贝出来的对象是全新的。和原来的对象没有任何关联
四 补充点
对于 如数字,字符,以及其他“原子类型”, 没有拷贝一说,产生的都是对原对象的引用