十.Python中深拷贝、浅拷贝

1.浅拷贝

浅拷贝,简单的理解,就是只拷贝了引用,但没有拷贝其内容。

举个例子,旅店小于的房间号302, 小于告诉了小明自己的房间号(假定知道房间号同时就有了进入房间的钥匙和权利),小于在房间中添加一把椅子,小明进入房间就可以看到。
小于忘记了自己房间号,但是通过小明还可以进入这个房间。

代码示例

In [1]: d1 = [1, 2, 3]  #小于的房间302

In [2]: d2 = d1  # 告知给小明

In [3]: print(id(d1),id(d2))  # 两人记忆的房间号302
140110307510784 140110307510784

In [6]: d1.append(4)  # 小于给302房间添加一把椅子

In [7]: d1  # 小于添加的,当然可以看到
Out[7]: [1, 2, 3, 4]

In [8]: d2 # 小明进入的也是302,自然也可以看到小于加的椅子
Out[8]: [1, 2, 3, 4]

In [9]: del d1  # 小于忘记了302房间

In [10]: d2  # 小明记得,
Out[10]: [1, 2, 3, 4]

In [11]: d1  # 当然Python中有垃圾回收机制
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-11-2d3a24957153> in <module>()
----> 1 d1

NameError: name 'd1' is not defined

这是一个很简单的浅拷贝,那看接下来的示例

In [17]: d3 = [1, 2]

In [18]: d4 = ['a', 'b']

In [19]: d5 = [d3, d4]

In [20]: d6 = d5

In [21]: import copy

In [22]: d7 = copy.copy(d5)

In [23]: print(id(d5), id(d6), id(d7))  # 发现d7的id与其他两个不一样
140110298615888 140110298615888 140110317120880

In [24]: d5.append('x')

In [25]: d5
Out[25]: [[1, 2], ['a', 'b'], 'x']

In [26]: d6
Out[26]: [[1, 2], ['a', 'b'], 'x']

In [27]: d7
Out[27]: [[1, 2], ['a', 'b']] # d7没有变化

In [28]: d3.append(3)

In [29]: d5
Out[29]: [[1, 2, 3], ['a', 'b'], 'x']

In [30]: d6
Out[30]: [[1, 2, 3], ['a', 'b'], 'x']

In [31]: d7
Out[31]: [[1, 2, 3], ['a', 'b']]  # d7同样有变化

上面的示例说明copy.copy只是复制最顶层的列表,但里面存放是依然相同的引用。

2.深拷贝

与浅拷贝对应的就是深拷贝,深拷贝是对于一个对象所有层次的拷贝。
代码示例

In [32]: import copy

In [33]: p1 = ['a', 'b']

In [34]: p2 = copy.deepcopy(p1)

In [35]: print(id(p1), id(p2))
140110298618608 140110298305312

In [36]: p1.append(3)

In [37]: print(p1, p2)
['a', 'b', 3] ['a', 'b']

In [38]: 

In [38]: b1 = ['a', 'b']

In [39]: b2 = [1, 2]

In [40]: c1 = [b1, b2]

In [41]: c2 = copy.deepcopy(c1)

In [42]: b1.append('c')

In [43]: c1
Out[43]: [['a', 'b', 'c'], [1, 2]]

In [44]: c2
Out[44]: [['a', 'b'], [1, 2]]

从结果可以看到深拷贝与浅拷贝的不同

3.不可变数据类型

copy.copy对于不可变类型,不会发生拷贝,它只是指向,但copy.deepcopy依然是拷贝
代码示例

In [45]: import copy

In [46]: t1 = ('a', 'b')

In [47]: t2 = copy.copy(t1)

In [48]: print(id(t1), id(t2))
140110307485168 140110307485168

In [49]: t3 = copy.deepcopy(t1)

In [50]: print(id(t1), id(t3))
140110307485168 140110307485168

posted @ 2020-05-16 11:24  leafgood  阅读(194)  评论(0编辑  收藏  举报