• 九浅一深(深浅拷贝)


    *拷贝python对象(浅拷贝、深拷贝)

    浅拷贝——
    对一个“对象”进行浅拷贝其实就是新创建了一个类型跟原对象一样,内容是原来对象元素的引用,
    换句话说:这个拷贝的对象本身是新的,但是内容不是。

    什么情况下是浅拷贝:
    1、完全切片 [:]
    2、工厂函数 比如:list(),dict()
    3、使用copy模块的copy函数

    演示浅拷贝特性

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    
    count = ['name',['saveings',100]]
    
    wife = count[:]
    
    husband = list(count)
    
    def view_list(*a):
    print(a)
    
    def view_id(*a):
    for i in a:
    print(id(i))
    
    view_list(wife,husband)
    view_id(count,wife,husband)
    
    wife[0] = 'Nichole'
    husband[0] = 'Alben'
    
    wife[1][1] = 50
    
    view_list(wife,husband)

    解析:
    定义1个count列表,其中两个元素,‘name’、‘[’saveings’,100]

    列表wife 通过完全切片拷贝而来

    列表husband 通过工厂拷贝而来

    第一次调用函数:view_list,结果
    (['name', ['saveings', 100]], ['name', ['saveings', 100]])
    第一次调用函数:view_id,结果
    34359816
    34360056
    34360976
    从id的值上看,这三个列表都是不同的对象。

    把"wife","husband"列表中的第一个值重定义:
    wife[0] = 'Nichole'
    husband[0] = 'Alben'
    把wife列表第二个元素(列表)中的第二个元素改为100(意味着老婆取款50)

    第二次运行函数:view_list与view_id的结果:
    (['Nichole', ['saveings', 50]], ['Alben', ['saveings', 50]])
    34228744
    34228984
    34229904

    我们会发现,"wife"和"husband"两个列表第二个元素中的第二个元素都改变了!

    why?
    因为是浅拷贝!
    但是为什么在修改"husband"列表[0]值的时候,没有同时修改"wife"呢?
    因为"wife","husband"两个列表的第一个元素是字符串(不可变对象)
    但是第二个元素时列表,是可变对象。
    所以在拷贝的时候,字符串被显式的拷贝了,并且创建了新的字符串对象,而列表只是把它的引用复制了一下,
    所以改变第二个对象的时候是两个引用会同时变化。

    验证:
    改变前
    print([id(x) for x in wife])
    print([id(x) for x in husband])
    结果:
    [4006400, 37112288]
    [4006400, 37112288]
    改变后:
    [34288320, 34294240]
    [34288384, 34294240]

    这样就很明显了,两个列表第一个元素“字符串”改变后,id值是不同的,但是第二个元素“列表”的id值是相同的。

    深拷贝:
    通过copy()函数的deepcopy()功能。
    修改上段代码:

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    
    import copy
    
    count = ['name',['saveings',100]]
    
    wife = count
    
    husband = copy.deepcopy(count)
    
    def view_id(*a):
    for i in a:
    print(id(i))
    
    
    def view_list(*a):
    print(a)
    
     
    
    wife[0] = 'Nichole'
    husband[0] = 'Alben'
    
    wife[1][1] = 50
    
    view_list(wife,husband)
    
    print([id(x) for x in wife])
    print([id(x) for x in husband])

    结果:
    (['Nichole', ['saveings', 50]], ['Alben', ['saveings', 100]])
    [34484928, 38064296]
    [34484992, 38065256]
    深拷贝是创建两个对象,所有id()结果两个元素对象的值都不同!

    关于深拷贝的注意点:
    第一,非容器类型(数字、字符串、其他‘原子’类型)没有被拷贝一说,例如元组,对他深拷贝是无效的。

  • 相关阅读:
    Activity的活动Menu和上下文Menu使用示例
    drawable之scale and rotate代码示例
    密度无关和缩放比例无关定义
    [前端优化]使用Combres合并对js、css文件的请求
    不同版本的SQL Server之间数据导出导入的方法及性能比较
    SqlBulkCopy加了事务真的会变快吗?
    ASP.NET Web Forms 4.5的新特性(二):针对HTML5的更新和Unobtrusive Validation
    MVC3缓存之一:使用页面缓存
    MVC3缓存之三:MVC3中的局部缓存(Partial Page)
    ASP.NET Web Forms 4.5的新特性(三):Model Binding
  • 原文地址:https://www.cnblogs.com/alben-cisco/p/6974399.html
Copyright © 2020-2023  润新知