1.什么是深浅拷贝
浅拷贝:只拷贝了对象的引用
深拷贝:拷贝的是对象的实质内容
例一:
a = ['a']
b = ['b']
c = [a, b]
d = c[:]
print 'a id:', id(a)
print 'c id:', id(c)
print 'd id:', id(d)
print 'c[0] id:', id(c[0])
print 'd[0] id:', id(d[0])
>>> a id: 39062544
>>> c id: 39364008
>>> d id: 39062664
>>> c[0] id: 39062544
>>> d[0] id: 39062544
从例一可以看出,d是c做切片操作获取的,c和d的id不同,可以说明c和d是两个不同的对象,但是我们进一步查看c和d的元素id,发现确是指向同一个对象,我们可以称这个为浅拷贝。
例一 图示
虽然d是c的一份copy,但是他们的元素其实是指向的同一个对象。
我们将例一的code重新变一下:
例二:
import copy
a = ['a']
b = ['b']
c = [a, b]
d = copy.deepcopy(c)
print 'a id:', id(a)
print 'c id:', id(c)
print 'd id:', id(d)
print 'c[0] id:', id(c[0])
print 'd[0] id:', id(d[0])
>>> a id: 39264168
>>> c id: 39548488
>>> d id: 39262648
>>> c[0] id: 39264168
>>> d[0] id: 39262608
例二 图示现在我们就可以很明显看出来c和d中的元素不在是同一个对象了,这就是深拷贝。
深拷贝其实是对原对象做了迭代拷贝,然后生成了一个新的对象,这个新生成的对象里里外外都是新的。
总结:
我们常用到的工厂函数例如list,dir等都是浅拷贝,当然切片操作[:]也是浅拷贝,copy模块的copy方法也是浅拷贝。
2.运用
如果在写代码过程中需要用到一个可变对象,但是又不想改变这个可变对象,这是即可使用深拷贝。
例三:
import copy
a = ['a']
b = ['b']
c = [a, b]
def do_something(arg):
arg.append(['c'])
return arg
_c = copy.deepcopy(c)
print do_something(_c)
print c
>>> [['a'], ['b'], ['c']]
>>> [['a'], ['b']]
|
补充:
对于不可变类型的对象来说则没有深拷贝的说法,比如对‘abc’做deepcopy,则新的引用还是指向原对象。对于元祖来说,分为包不包含可变对象,包含则可以进行深拷贝,如果都是不可变对象,则无法深拷贝。