自己的学习或者面试的过程中经常会遇到python深拷贝浅拷贝的问题,大部分的笔试或者面试题都要求写代码来表现python中浅、深拷贝的区别,刚开始学习的时候我大体知道他们直接的区别,但是理解的不够深刻,网上很多帖子也是通过举例来说明他们之间的区别,至于为什么浅、深拷贝之间会有这样的区别,我还没看到帖子中有一针见血的指出过区别。
首先要明白的一点在python中我们使用对象时使用的是什么? 比如说 a = 1, b = [1, 2, 3], 我们在使用a , b是使用的数字1 和列表[1, 2, 3]的引用。注意是引用、引用! python对象的本质是引用。
第二个问题是python中参数传递方式归根到底是值传递:
a = 1
b = [1, 2, 3]
c = [7, 8, 9]
def test_func(a, b, c): # 参数传递是值传递,在函数内部修改值不会影响外层的值
a += 1
b = [4, 5, 6]
c.append(10)
test_func(a, b, c)
print(a, b) # 1, [1, 2, 3], [7, 8, 9 10]
回到浅、深拷贝的话题上来,a = [1, 2,3] b = [4, 5,6] d = {"1":a, "2":b},浅拷贝x = copy(x) y = copy.deepcopy() 他们之间归根到底的区别就是浅拷贝只是复制了最外层的引用,深拷贝复制的内外层的所有拷贝(特殊的对于不可变对象深拷贝内层对象的引用还是不变)。
In [35]: a = [1, 2,3]
In [36]: b = [4, 5,6]
In [37]: d = {"1": a, "2":b}
In [38]: id(d)
Out[38]: 4563267448
In [39]: x = copy.copy(d)
In [40]: id(x)
Out[40]: 4563142192
In [41]: id(d["1"])
Out[41]: 4562874312
In [42]: id(x["1"])
Out[42]: 4562874312
浅拷贝可以看到id(d) != id(x)但是里层相等
In [42]: id(x["1"])
Out[42]: 4562874312
In [43]: y = copy.deepcopy
In [44]: y = copy.deepcopy(d)
In [45]: id(y)
Out[45]: 4563683368
In [46]: id(y["1"])
Out[46]: 4556112200
深拷贝里层的id也不相等,所以在其他的才会出现在其他博客讲解中出现的表现方式不一样,我就不在举例说明啦。