【Python教程】十七、在Python里搞克隆|浅拷贝与深拷贝

本文介绍了Python中对象的复制操作,包括浅拷贝和深拷贝的概念。浅拷贝仅复制对象的引用,而深拷贝则创建完全独立的新对象。通过实例展示了浅拷贝如何在列表嵌套时导致意外的共享关系,以及如何使用`copy`模块的`deepcopy`函数实现深拷贝,确保修改副本不会影响原始对象。文章强调了理解和正确使用拷贝方法在避免程序错误中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更多教程请私信~

来源:思路实验室 

作者:室长

大家好,欢迎收看思路实验室出品的Python入门教程,我是室长。

大家好,欢迎收看思路实验室出品的Python入门教程,我是室长。

在之前的学习中,我们得到了几条基础知识:

1.在Python中,万物皆对象。

2.对象分为可变对象和不可变对象。

3.变量里存储的不是值,而是对象所在的内存地址。

那么当可变对象发生变化的时候,并不代表着它的内存地址也发生变化。所以就会出现这样的情况:

周树人起了个笔名叫鲁迅,但是不管是周树人还是鲁迅都是同一个人。“抓捕周树人跟我鲁迅有什么关系”纯粹是因为抓人的吃了没文化的亏。

我让变量a和变量b同时指向一个可变对象(比如列表、字典和集合),然后改变这个对象,那通过访问变量a和变量b得到的结果都会发生改变。

但是在实际使用中,我们往往不希望进行这样的操作,而是希望a和b是不同的列表,只不过是值一样,对其中一个的改变不影响另一个。这时候用等号去赋值就不管用了。

好在,常见的可变对象都有一个copy方法,用来对这个对象进行克隆,生成一个一模一样的对象(给鲁迅克隆一个周树人来顶包,好像顺序不对)

这里b虽然和a一开始的值一样,但已经不是同一个列表了。当使用了copy方法之后,a走a的阳关道,b过b的独木桥,从此山高路远,纵马扬鞭……

然而真的就从此不再有关系了吗?我们来看这样一个例子:

这里的a是一个嵌套列表的列表:

我们使用copy方法克隆一下这个列表:

没有问题。我们改动一下a列表:

b并没有受到影响,那如果我们改动一下c呢?

明明是克隆了一个新列表,怎么b还跟c有关系?

我们以为,一旦用copy方法克隆了a,克隆后的列表就是[1,[1,2]]了,但事实上并非如此,克隆后的列表仍是[1,c]。

所以我们不难看出,列表里存储的也并非是具体的对象,而是对象所在的内存地址。同理,作为可变对象的字典和集合也是如此。

我们使用copy方法克隆的是当前对象存储的内容,也就是一系列的内存地址,而不是具体的值。因此这个copy方法被称为浅拷贝

而有时候我们就希望能够把当前对象里的所有值克隆下来,成为一个完全独立的新对象,任何别的地方的改动都影响不到它。这当然可以,而这种方法被称为深拷贝。不过深拷贝就不是对象自带的方法了,我们需要使用copy模块里的deepcopy函数

这一期我们了解了浅拷贝和深拷贝的操作方法。在实际操作中,常常存在对可变对象直接使用等号赋值而没有用拷贝方法或者用错拷贝方法导致的错误。变量值、列表(集合)元素、字典键值,本质上都是对象的内存地址。牢记这一点,你就可以正确地运用等号赋值和拷贝方法。

在编写程序的时候,我们都是要做到没有bug不报错的。但是有些时候运行程序时需要外界的输入,而这些输入不一定就符合程序的要求。如果就因为输入的错误导致了程序整个报错关闭,那有问题的不是输入而是程序本身。那要如何避免这种问题呢?请关注下期:这根本就不是我的错嘛!Python的异常处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值