Python对象的浅拷贝与深拷贝

58 阅读3分钟

看了上面这张图,相信大家已经对直接赋值和拷贝有了一个比较清楚的认识。

直接赋值:复制一个对象的引用给新变量

拷贝:复制一个对象到新的内存地址空间,并且将新变量引用到复制后的对象

我们的深浅拷贝只是对于可变对象来讨论的。 不熟悉的朋友需要自己去了解可变对象与不可变对象哦。

1. 对象的嵌套引用


a = { "list": [1,2,3] }

上面的代码,在内存中是什么样子的呢?请看下图:

原来,在我们的嵌套对象中,子对象也是一个引用。

1. 浅拷贝


如上图所示,我们就可以很好的理解什么叫做浅拷贝了。

浅拷贝:只拷贝父对象,不会拷贝对象的内部的子对象。内部的子对象指向的还是同一个引用

上面 的 a 和 c 是一个独立的对象,但他们的子对象还是指向统一对象

1.1 浅拷贝的方法


  • .copy()

a = {"list": [1,2,3] }

b = a.copy()

  • 列表切片[:]

a = [1,2,3,[1,2,3]]

b = a[1:]

a = [1,2,3,[1,2,3]]

b = []

for i in a:

b.append(i)

1.2 浅拷贝的影响


a = {"list":[1,2,3]}

b = a.copy()

a["list"].append(4)

print(a)

{'list': [1, 2, 3, 4]}

print(b)

{'list': [1, 2, 3, 4]}

在上面的例子中,我们明明只改变 a 的子对象,却发现 b 的子对象也跟着改变了。这样在我们的程序中也许会引发很多的BUG。

2. 深拷贝


上面我们知道了什么是浅拷贝,那我们的深拷贝就更好理解了。

深拷贝:完全拷贝了父对象及其子对象,两者已经完成没有任何关联,是完全独立的。

import copy

a = {"list":[1,2,3]}

b = copy.deepcopy(a)

a["list"].append(4)

print(a)

{'list': [1, 2, 3, 4]}

print(b)

{'list': [1, 2, 3,]}

上面的例子中,我们再次修改 a 的子对象对 b 已经没有任何影响

3. 手动实现一个深拷贝


主要采用递归的方法解决问题。判断拷贝的每一项子对象是否为引用对象。如果是就采用递归的方式将子对象进行复制。

现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。

分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

了解详情:docs.qq.com/doc/DSnl3ZG…