Python 深浅复制

Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变的或包含可变项的容器,有时需要一个副本,所以可以改变一个副本而不改变另一个。


浅复制

将创建一个新对象,但它包含的是对原始对象包含的项的引用。

a = [] 
b = list(a)
c=a.copy()
d = copy.copy(a)

深复制

创建一个新对象,并且递归的复制他包含的所有对象。

import copy 
b = []
a = copy.deepcopy(b)

当原始对象中包含可变对象a,浅复制仅仅复制对a的引用

这时,如果a的值更改,那么相应新对象中a的值也会更改

>>> a=[1,2,3]
>>> b = {'x':['a','b'], 'y':a}    #字典b的value都是可变对象

>>> c = copy.copy(b)        #浅复制
>>> d = copy.deepcopy(b)    #深复制

>>> a.pop()                #修改a
3
>>> b
{'x': ['a', 'b'], 'y': [1, 2]}    #原始对象b改变
>>> c
{'x': ['a', 'b'], 'y': [1, 2]}    #浅复制c同样发生改变
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3]}    #深复制d不变

>>> b['x'].append('c')
>>> b
{'x': ['a', 'b', 'c'], 'y': [1, 2]}
>>> c
{'x': ['a', 'b', 'c'], 'y': [1, 2]}
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3]} 

使用内置函数id()来查看对象的标识

                        标识相当于内存中对象中的地址

>>> id(a)
50285512
>>> id(b['y'])
50285512
>>> id(c['y'])        
50285512
>>> id(d['y'])
49946056

可以发现原始对象b['y']和浅复制对象c['y']的标识相同,和a引用同一个值,而深复制对象d['y']引用的是一个新的值


        所以将a添加到浅复制对象c['y']中会导致递归引用

>>> a
[1, 2]
>>> c['y'].append(a)
>>> c
{'x': ['a', 'b', 'c'], 'y': [1, 2, [...]]}    #c['y']出现递归引用
>>> a.pop()        #删除a中对a的引用
[1, 2]
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3, [1, 2]]}    #d['y']和a引用的不是一个值,所以不会发生诋毁引用

实现简单的深浅复制

def mycopy(x):
    '''浅复制函数,接受list,tuple,set,dict类型的参数'''
    types = {list,tuple,set}
    cls = type(x)
    if cls in types:
        n = [item for item in x]
        return cls(n)
    elif cls is dict:
        return {key:value for key,value in x.items()}
    raise TypeError






猜你喜欢

转载自blog.csdn.net/DAGU131/article/details/79369667
今日推荐