标签:
浅拷贝:字符串被显示的拷贝,列表元素的引用被拷贝,因此修改例如字符串这种不可变的值,不会在被拷贝的对象中有改变。
深拷贝:字符串被显示的拷贝,列表被完全拷贝(创建了一个新对象,内容和之前的列表一致)。
不管是浅拷贝还是深拷贝,被拷贝的字符串这种不可变的值一开始的id都是一样的,不管是深浅都是新建了一个对象,而不是像引用赋值那样只是多加了一个对对象的引用。
下面用id()函数来说明这种变化。
>>> p = [‘name‘, [‘saving‘, 100]] >>> h = p[:] >>> [id(x) for x in p, h] [4490260704, 4490336016]
浅拷贝的两个对象id不同,说明是两个对象。但是如果只是增加了一个对对象的引用,那么id就完全一样。
>>> p [‘name‘, [‘saving‘, 100]] >>> x = p >>> [id(x) for x in p, x] [4490260704, 4490260704]
接着说重点,浅拷贝的两个对象本身的id就不同,然后我们看其中的元素,经测试,没被修改的浅拷贝中的不可变元素(name)id一致,这里我们不探讨这个,重点在后面的list,看看二者的id知否一致。
>>> p [‘name‘, [‘saving‘, 100]] >>> h [‘name‘, [‘saving‘, 100]] >>> [id(x[1]) for x in p, h] [4490174336, 4490174336]
我们再试试深拷贝。
>>> p [‘name‘, [‘saving‘, 100]] >>> import copy >>> w = copy.deepcopy(p) >>> [id(x[1]) for x in p, h, w] [4490174336, 4490174336, 4490337744]
我们可以发现,深拷贝的list的id却是变了,说明是完全新建了一个list对象。
我们再试试不可变元素。
>>> p [‘name‘, [‘saving‘, 100]] >>> h [‘name‘, [‘saving‘, 100]] >>> [id(x[0]) for x in p, h] [4489215600, 4489215600] >>> h[0] = ‘hs‘ >>> [id(x[0]) for x in p, h] [4489215600, 4490618080]
id不同,说明现在name处的string是完全两个元素了。
下面试一下元组,如果元组中的元素只包含不可变对象,那么对他进行深拷贝会发生什么。
>>> p [‘name‘, (‘saving‘, 100)] >>> w = copy.deepcopy(p) >>> [id(x[1]) for x in p, w] [4490184464, 4490184464]
可以发现,如果元组中的元素都是不可变类型,那么对元组进行深拷贝也是浅拷贝。
我们再试下如果元组中包含list的情况。
>>> p [‘name‘, (‘saving‘, [100])] >>> w = p[:] >>> del w >>> w = copy.deepcopy(p) >>> [id(x[1]) for x in p, w] [4490184392, 4490181520]
如果元组中包含可变对象,那么深拷贝对元组的深拷贝就是起作用。
总结:浅拷贝拷贝的是可变对象的引用,真正的深拷贝是新建了一个对象,内容跟原来的一致。
标签:
原文地址:http://www.cnblogs.com/iNeoWong/p/4725015.html