• python学习之【深拷贝】


    #我的编程语言学习笔记#

    前言

    上一篇文章python学习之【浅拷贝】 学习了python中的浅拷贝相关内容,这篇文章接着学习深拷贝。

    简单回顾

    浅拷贝只拷贝浅层元素,深层元素的内存地址不改变当对拷贝产生的新的对象的浅层元素进行更改时,原对象的主元素不做改变;但是对拷贝后产生的对象的深层对象进行改变时,那么原对象的深层元素的地址就会发生变化。

    在这里插入图片描述

    而python中的深拷贝(deepcopy) 不仅会拷贝对象的主层元素,深层元素也会拷贝。

    举例

    我们同样先举列表进行深拷贝的例子,注意在进行深拷贝时我们需要先引入一个 copy 模板块:

    #深层拷贝需要引入一个 拷贝python copy模板块
    import copy
    
    • 1
    • 2

    然后利用列表来验证深拷贝:

    import copy
    
    a=[11,22,33,[1,2,3,[4,5]]]
    d=copy.deepcopy(a)
    print('--------------a的相关信息-------------')
    print(a,id(a))   #[11, 22, 33, [1, 2, 3, [4, 5]]] 2196544302400
    print('------------a中元素的相关信息--------------')
    print(a[0],id(a[0]),a[1],id(a[1]),a[2],id(a[2]))
    #11 140721422918760 22 140721422919112 33 140721422919464
    a[3][1],id(a[3][1]))
    # 2 140721422918472
    print(a[3][3][1],id(a[3][3][1]))
    # 5 140721422918568
    
    
    print('-------------d的相关信息--------------------')
    print(d,id(d))   #[11, 22, 33, [1, 2, 3, [4, 5]]] 2196544300928
    print('-------------d中元素的相关信息----------------')
    print(d[0],id(d[0]),d[1],id(d[1]),d[2],id(d[2]))
    
    # 11 140721422918760 22 140721422919112 33 140721422919464
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    由于列表是可变序列,因此我们无法从id地址上看出内存地址的关系图;但是我们可以通过改变拷贝后得到的对象d的值来查看内存的变化情况:

    print('-----------------改变深拷贝后的浅层元素和深层元素-----------------')
    d[2]=100
    print('改变拷贝后的对象的浅层元素后的a的相关信息:',a[2],id(a[2]))
    #改变拷贝后的对象的浅层元素后的a的相关信息: 33 140721422919464
    
    d[3][1]=999
    d[3][3][1]=888
    print('改变拷贝后的对象d的深层元素后的a的相关信息:',a[3][1],id(a[3][1]))
    # 改变拷贝后的对象d的深层元素后的a的相关信息: 2 140721422918472
    print(a[3][3][1],id(a[3][3][1]))
    # 5 140721422918568
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过运行结果我们可以看出:无论是改变d的浅层元素还是深层元素,原对象a的id地址都不会发生改变,这就说明,深拷贝deepcopy 会将对象的深层对象和表层对象都拷贝,形成一个新的对象。

    因此它的内存图是这样的:
    在这里插入图片描述

    类的深拷贝

    # python中的深拷贝
    class CPU():
        pass
    class Disk():
        pass
    class Computer():
        def __init__(self,cpu,disk):
            self.cpu=cpu
            self.disk=disk
    cpu1=CPU()
    disk1=Disk()
    print('cpu1的信息:',cpu1,id(cpu1))
    print('disk1的信息:',disk1,id(disk1))
    '''
    cpu1的信息: <__main__.CPU object at 0x7f7b6e4fca90> 140168108427920
    disk1的信息: <__main__.Disk object at 0x7f7b6e4fcb10> 140168108428048
    '''
    # 不要忘记传参
    computer1=Computer(cpu1,disk1)
    # 传入拷贝模板
    import copy
    computer3=copy.deepcopy(computer1)
    print('computer1的相关信息',computer1,id(computer1),computer1.cpu,computer1.disk)
    print('---------------深拷贝后的对象的信息——computer3-------------\n')
    print('computer3的相关信息',computer3,id(computer3),computer3.cpu,computer3.disk)
    '''
    computer1的相关信息 <__main__.Computer object at 0x7f92ae4b9bd0> 140267966143440 <__main__.CPU object at 0x7f92ae4b9ad0> <__main__.Disk object at 0x7f92ae4b9b50>
    computer3的相关信息 <__main__.Computer object at 0x7f92ae4b9c90> 140267966143632 <__main__.CPU object at 0x7f92ae4bd890> <__main__.Disk object at 0x7f92ae468c50>
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    同样的,我们画出相应的内存图:
    在这里插入图片描述

    每篇一语

    凡事预则立,不预则废!

    如有不足,感谢指正!

  • 相关阅读:
    2022/8/3 考试总结
    RFID锁控系统助力铁路智能巡检,实现铁路锁控精细化管理
    【机器学习基础】无监督学习(5)——生成模型
    MySQL学习第二部分:索引特性
    南卡电容笔和欢能哪个更推荐呢?Ipad好用电容笔对比
    Linux多线程C++版(五) 线程同步和线程互斥
    (c语言进阶)指针的进阶
    vue3 el-form中嵌套el-tabale 对输入动态校验
    [Linux]如何理解kernel、shell、bash
    CG-34 浊度传感器 简单说明
  • 原文地址:https://blog.csdn.net/weixin_64122448/article/details/132702043