Python(一):类的深拷贝和浅拷贝

1.定义区分

变量的赋值:只是形成两个变量,实际上还是指向同一个对象
浅拷贝:拷贝时,对象包含的子对象内容不拷贝,因此源对象和拷贝对象引用的是同一个对象
深拷贝:使用copy模块的deepcopy函数。递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。

2.代码演示

看定义可能会觉得有点深奥,难以理解。不过没关系结合图形和代码来进行演示,更加深入地理解底层实现原理。

1.定义三个类CPU,Disk,Computer,其中Computer的属性包含有前两个类对象。

class CPU:
    pass

class Disk:
    pass

class Computer:
    def __init__(self,cpu,disk):
        self.cpu = cpu 
        self.disk = disk
2.1 变量的赋值

只是形成两个变量,实际上还是指向同一个对象

变量的赋值是使用“=”来完成的。
变量的组成:标识(对象所存储的地址 id(obj)+类型(对象的数据类型type(obj))+值(存储的值(print(obj))

# 声明一个cpu1变量并将CPU实例对象赋予它
cpu1 = CPU()
print(cpu1,id(cpu1))
# 将cpu1赋予cpu2
cpu2 = cpu1
print(cpu2,id(cpu2))

输出结果:

<__main__.CPU object at 0x00000182116B6820> 1658149627936
<__main__.CPU object at 0x00000182116B6820> 1658149627936

可以看到cpu1和cpu2的id值是一致的,说明这两个变量是相同的。通过内存图进一步显示赋值的实现过程。
如下面的内存图所示,cpu1和cpu2两个变量的id值均为“…7936",说明引用的都是同一个对象。
在这里插入图片描述

2.2 浅拷贝

拷贝时,对象包含的子对象内容不拷贝,因此源对象和拷贝对象引用的是同一个对象

代码实例:

import copy
disk = Disk()
comp1 = Computer(cpu1, disk)
print(comp1,id(comp1),id(comp1.cpu),id(comp1.disk))
comp2 = copy.copy(comp1)
print(comp2,id(comp2),id(comp2.cpu),id(comp2.disk))

输出结果:comp1和comp2对应的id不相同,而子对象对应的id是相同的。

<__main__.Computer object at 0x000001FAFD3986A0> 2177501857440 2177503160352 2175472490912
<__main__.Computer object at 0x000001FAFD4AC460> 2177502987360 2177503160352 2175472490912

接下来用图片的方式分析下内存图,就可以很清楚的明白这里的原理啦。
在这里插入图片描述
从图上可以看出变量comp1和comp2分别指向两个不同的对象实例,是对原有的对象实例的一个拷贝,而在对象中的子对象cpu和disk指向同一个对象实例,因此为浅拷贝。

2.3 深拷贝

使用copy模块的deepcopy函数。递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

在理解了浅拷贝之后,深拷贝也就容易了。它们两个的不同之处在于,子对象是否进行了拷贝。

import copy
disk = Disk()
comp1 = Computer(cpu1, disk)
print(comp1,id(comp1),id(comp1.cpu),id(comp1.disk))
comp3 = copy.deepcopy(comp1)
print(comp3,id(comp3),id(comp3.cpu),id(comp3.disk))

输出结果:从结果可以看出来不管是comp3和comp1的id,还是子对象的id都互不相同,说明对象实例以及子对象实例都进行了拷贝,属于深拷贝。

<__main__.Computer object at 0x000001FC093586A0> 2181997889184 2181999192096 2182115809696
<__main__.Computer object at 0x000001FC0946C490> 2181999019152 2182117519712 2182117519904

内存图分析:从图中也可以很明显看出来Computer对象实例有两个,Disk以及CPU也有两个,即都进行了拷贝,所以这就是深拷贝啦。
在这里插入图片描述
结合上面的例子就很容易区别深拷贝和浅拷贝的差异啦,深拷贝是进行一个递归的拷贝,而浅拷贝只是拷贝了表层的东西。

3.深拷贝和浅拷贝的使用场景

深拷贝:改变子对象的值不会影响到源对象的值。
浅拷贝:改变子对象的值都会影响到源对象的值。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值