python-深拷贝与浅拷贝

xiaoxiao2021-02-28  99

python-深拷贝与浅拷贝


1.可变对象与不可变对象

要想区分python的深拷贝与浅拷贝,首先要区分python的可变对象与不可变对象。这个在我的上一篇python笔记中,已经有所阐述。

可变对象包括字典(dictionary)、列表(list)。不可变对象包括int、字符串(string)、浮点型(float)、数值型(number)、元组(tuple)。对不可变对象的连接、替换、去除等操作将产生新的对象。对可变对象的操作可能产生新的对象,也可能不产生新的对象。

2.对象赋值、浅拷贝、深拷贝

关于这三个概念的区别,我这里只写结论,如果想看具体的例子,可以参考这一篇博客(http://www.cnblogs.com/wilber2013/p/4645353.html)。

在考虑对象赋值、浅拷贝和深拷贝的相关问题时,一定要考虑它们在内存中的存储情况首先,拷贝的说法只针对容器类型,对于非容器类型(如数字、字符串、和其他’原子’类型的对象)没有拷贝的所法。如果元祖变量只包含原子类型对象,不能对其进行深拷贝(即对其深拷贝不会产生新的对象)。

①对象赋值(Object1 = Object2)

并不会创建新的对象,仅仅创建一个引用,指向相同的对象。由于两个引用指向的是相同的对象,所以对一个引用指向对象的操作(无论是对可变对象的操作还是对不可变对象的操作)会影响另外一个引用所指向的对象。

②浅拷贝(Object1 = copy.copy(Object2))

首先,浅拷贝会得到一个新的对象。在内存中,新的对象中的元素并不会重新创建,而是仍然利用原有对象中的元素(新对象元素的引用指向原对象的元素)。对某个对象的某个元素进行操作(连接、替换、去除等)时, 如果该元素是不可变对象,则该操作不会影响到另外一个对象(因为此时内存中创建了一个新的元素对象,而另外一个对象的元素仍然指向旧的元素对象);如果该元素是可变对象,则该操作会影响到另外一个对象(因为此时内存中没有创建新的对象,只是对原有元素对象进行了改变,而两个对象均有指向该元素的引用)。

使用下面的操作的时候,会产生浅拷贝的效果:

使用切片[:]操作使用工厂函数(如list/dir/set)使用copy模块中的copy()函数

③深拷贝(Object1 = copy.deepcopy(Object2))

深拷贝也会创建一个新对象对象中的元素,如果是可变对象的话就会被重新创建;如果是不可变对象的话就先不会被重新创建(由于是不可变对象,为了节省内存,没有重建的必要)。对某个对象的某个元素进行操作(连接、替换、去除等)时,均不会影响到另外一个对象的元素: 如果进行操作的元素是不可变对象,由于在内存中二者指向的是不同的元素对象,所以对一个对象元素的改变并不会影响到另外一个对象;如果进行操作的元素是可变对象,则产生改变的对象会创建一个新的元素对象并指向它,而另外一个对象不受其影响。

最后,还想再次重申,如果在对象赋值、浅拷贝、深拷贝的问题上产生疑惑,一定要考虑在操作过程中,对象在内存中的存储状况。

转载请注明原文地址: https://www.6miu.com/read-34158.html

最新回复(0)