• python学习笔记:引用、浅拷贝和深拷贝(底层原理)


    前言

    在python中“一切皆对象”,包括整数(int),小数(float)等

    引用

    Python解释器维护了一个内部的数据结构,称为命名空间或符号表,它将变量名与对象的内存地址关联起来。当您创建一个变量并将其赋值为某个对象时,实际上是将变量名与对象的内存地址关联起来,从而使变量可以引用该对象。

    在python中,变量是一个标识符,解释器遇到这个标识符的时候,会在python的“符号表”里面对应它的位置,并返回它对应的对象的地址。在赋值操作时,符号表将会被编辑,标识符对应的对象地址被改变,使得变量可以引用新的对象。

    比如:当我执行:

    1. a = ‘hello’
    2. b = 'world'

    拓展:

    python的不可变对象用的是引用计数机制。为了节省内存和提高效率,如果创建多个值相同的变量,他们指向的对象一般是相同的。比如

    1. a = 1
    2. b = a
    3. c = b

    执行完这段代码之后,a,b,c都指向同一个地址(同个对象),这个地址的引用次数为3。但是当我们改变其中一个变量的值(实际上是想要改变变量引用的对象的值)得时候,其他两个变量的值不会改变。这是为什么?这是因为int是不可变类型,所以实际上当你想要改变变量引用的对象的值的时候,不会真的改变这个对象的值,而是新建了一个对象,然后让变量引用这一个新的对象,相应地“1”的引用次数减少为2。

    若执行:b = 2,不会改变0x11的值,而是在内存里新建一个值为2的对象:

    (当地址的引用次数变为0,python会回收这块内存。)

    浅拷贝

    哪些操作属于:除了copy 模块中的 deepcopy 函数,其他均为浅拷贝

    就是只拷贝一层的信息,不管是拷贝最外层的引用(直接赋值),还是次外层的引用(切片),只一层。

    深拷贝

    只有 copy 模块中的 deepcopy 函数能够实现

    新建新的对象,递归重建完全一样的引用结构。

    浅拷贝和深拷贝的区别

    浅拷贝和深拷贝的区别不在深浅,而在对引用结构的拷贝是全面的还是部分的。

    有时候浅拷贝操作的效果和深拷贝完全相同,比如

    1. a = [1, 2, 3]
    2. b = a[:]
    3. a[0] = 4
    4. print(b[0])

    这时b[0]的值没有改变还是1,也就是b = a[:]等价于 b = copy.deepcopy(a)

    这是因为切片虽然是浅拷贝,但是不是拷贝a数组这个对象的引用,而是a数组内容里面每个对象的引用,由于前文提到的int类型对象的不可变性,当我们尝试改变a[0]引用的整型对象的值得时候,会新建一个新对象,这个对象的值被改成4,这就和b没什么关系了。

    所以我把切片赋值这样的浅拷贝称为“拷贝次外层”的浅拷贝。和我用循环通过下标赋值类似。

    但当浅拷贝对象是可变对象时,浅拷贝和深拷贝的区别就显现出来了:

    示例:

    1. a = [1, 2, [3, 4]]
    2. b = a[:] # 切片操作
    3. b[0] = 100 # 修改 b 的第一个元素
    4. b[2][0] = 300 # 修改 b 的嵌套列表中的元素
    5. print(a) # 输出:[1, 2, [300, 4]]

    在上述示例中,切片复制了包含整数的部分,因此修改 b[0] 不会影响 a,但它仍然共享嵌套列表中的引用,因此修改 b[2][0] 也会影响 a。这说明切片是浅拷贝的行为,只适用于最外层的元素。

    总结一下,就是如果改变一个变量,另一个也跟着改变了,就是因为两个引用了相同的可变对象。

    有什么问题,欢迎评论提出。

  • 相关阅读:
    为不同的调制方案设计一个单载波系统(映射器-信道-去映射器)(Matlab代码实现)
    香,一套逻辑轻松且智能解决PyQt中控件数值验证的问题
    Unity3D Entity_CacheService实现详解
    Linux原子操作与锁实现
    迅镭激光万瓦切割设备中标全球轨交装备龙头中国中车
    Chronos——中
    K210入门必看(MAIX DOCK)(一)
    数据结构之 LinkedHashMap 与 TreeMap
    计算机毕业设计项目选题推荐(免费领源码)java+mysql二手校园交易平台67613
    排查SQLSERVER数据库慢-查询SQLSERVER数据库占用资源SQL语句
  • 原文地址:https://blog.csdn.net/Com_man_der/article/details/133977705