最近在编程过程中遇到了深拷贝与浅拷贝的问题,属于细节问题,不在乎的话可能会出问题,故进行总结。
在Python中,对象赋值在本质上是对对象的引用,当创建一个对象把它赋值给另一个变量的时候,Python并没有拷贝这个对象,而只是拷贝了这个对象的引用,
1.浅拷贝
copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
也就是说当复制对象里面有嵌套数组时,里面嵌套的数组不会被复制。
2.深拷贝
copy.deepcopy 深拷贝 拷贝对象及其子对象。但是,对象里依然包含不可变元素与可变元素。
不可变元素包含:int,float,complex,long,str,unicode,tuple
可变原生:list
举例说明:
import copy
a = [1, 2, 3, 4, ['你好', '朋友']]
b = a # 赋值,传对象的引用
c = copy.copy(a) # 浅拷贝,对象拷贝
d = copy.deepcopy(a) # 深拷贝,对象拷贝
a.append(5) # 修改对象a,列表末尾添加数字5
a[4].append('世界') # 修改对象a中的列表
print 'a= ', a
print 'b= ', b
print 'c= ', c
print 'd= ', d
输出结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] # 修改了原始对象,变为修改后的列表
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5] # 对象的引用,对象的任何值变化都随着变化
c = [1, 2, 3, 4, ['a', 'b', 'c']] # 浅拷贝,不可变元素不能改变,可变元素随着原始对的变化而变化了
d = [1, 2, 3, 4, ['a', 'b']] # 深拷贝,原始对象的值发生任何变化,深拷贝新的对象内存地址不会发生任何变化
参考:http://t.csdn.cn/3svJr
深拷贝的缺点
深拷贝在某些情况下可能会存在一些缺点,比如:
-
性能问题。深拷贝需要递归复制整个数据结构,当数据结构比较大时,时间和空间复杂度会比较高。
-
可能会产生循环引用。如果数据结构中存在循环引用,深拷贝会导致无限递归,可能会导致内存溢出等问题。
下面是一个使用深拷贝会产生循环引用的例子:
import copy
class A:
def __init__(self):
self.b = None
class B:
def __init__(self):
self.a = None
a = A()
b = B()
a.b = b
b.a = a
c = copy.deepcopy(a) # 深拷贝可能会导致无限递归,导致内存溢出
在这个例子中,对象a和b之间存在循环引用,当使用深拷贝时,会导致无限递归,最终导致内存溢出。因此,在使用深拷贝时,需要注意数据结构中是否存在循环引用等情况。