python 踩坑系列之深浅拷贝

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,则新的引用还是指向原对象。对于元祖来说,分为包不包含可变对象,包含则可以进行深拷贝,如果都是不可变对象,则无法深拷贝。

猜你喜欢

转载自blog.csdn.net/u011877410/article/details/81706454