• day07 深浅拷贝


    今日概要

    • 深浅拷贝(重点)
    • 文件操作

    详细内容

    • 直接赋值: 直接将对象的引用赋值给另一个对象

      v1=1000
      v2=v1
      #v1 v2指向同一个内存地址
      print(id(v1),id(v2))#相等
      v1="new_value
      print(id(v1),id(v2))#不等
      
      v1=[1,2,3]
      v2=v1
      ##v1 v2指向同一个内存地址
      v1.append("45")
      print(v2)
      #[1,2,3,4,5]
      ##v1 v2指向同一个内存地址  修改v1内存地址的内容  v2也会跟着改变
      

      Memory

      解析:
      变量中存放的都是引用地址
      当创建v1并赋值的时候,会在内存空间开辟一小块内存空间比如(001):001=1000
      v1存放该1000内存地址
      当v2=v1的时候  将该内存地址又给了v2 ==>v2也指向 001 地址 ==> v2==1000
      当v1="新变量时候" 因为 001存放的1000是不可变类型 v1需要另外开辟空间004:存储"new_value"
      此时v2还是指向001内存地址
      
      
      
    • 浅拷贝: 只拷贝父对象,不会拷贝子对象(只会copy一层)

    • 深拷贝:会拷贝到所有嵌套的子对象

      1. 不可变类型的copy

        按理说会另外开辟一块空间存放v2的“alex”值 ,但是由于小数据缓存池原因,使“alex”只会占用一个内存,所以v2和v1地址相等

        #1.字符串及其int型的copy
        v1="alex"
        import copy
        v2=copy.copy(v1)
        print(id(v1),id(v2))#相等
        
        #按理说会另外开辟一块空间存放v2的“alex”值 ,但是由于小数据缓存池原因,使“alex”只会占用一个内存,所以v2和v1地址相等
        
        #2.字符串及其int型deepcopy
        v3=copy.deepcopy(v1)
        print(id(v1),id(v2))
        #同理  地址相等
        
        
        
      2. 列表列表,集合,字典的拷贝

        #1.赋值
        v1=[1,2,3]
        v2=v1
        print(v2 is v1)#True
        v1.append("a")
        print(v1,v2)
        #[1,2,3,"a"]-->v1
        #[1,2,3,"a"]-->v2
        
        #2.copy
        v1=[1,2,3]
        import copy
        v3=copy.copy(v1)
        print(v3 is v1)#False
        v1.append("abc")#对v1指向的地址进行内部修改
        print(v1,v3)
        #[1,2,3,"abc"]-->v1
        #[1,2,3]     --->v3
        
        #3.copy
        import copy
        v1 = [1,2,3,{"name":'Gao',"numbers":[7,77,88]},4,5]
        v2 = copy.copy(v1)
        
        print(v1 is v2)#False
        
        print(v1[0] is v2[0])#True
        print(v1[3] is v2[3])#True
        
        print(v1[3]['name'] is v2[3]['name'])#True
        print(v1[3]['numbers'] is v2[3]['numbers'])#True
        print(v1[3]['numbers'][1] is v2[3]['numbers'][1])#True
        
        
        
        #3.deepcopy
        v1=[1,2,3]
        import copy
        v4=copy.deepcopy(v1)
        print(v4 is v1)#False
        v1.append("aaa")
        print(v1,v4)
        #[1,2,3,"aaa"]
        #[1,2,3]
        
        
      3. (有嵌套)列表,集合,字典的拷贝

        
        v1=[1,2,3,["a","b"]]
        import copy
        
        #1.浅拷贝
        v3=copy.copy(v1)
        print(v3 is v1)#不等
        v1.append("GG")#v1添加
        print(v1,v3)
        #[1, 2, 3, ['a', 'b'],'GG']  --->v1
        #[1, 2, 3, ['a', 'b']]       --->v3
        #v1的第一层列表改变后,v3没有改变
        
        v1[3].append("c")
        print(v1,v3)
        #[1, 2, 3, ['a', 'b', 'c'], 'GG'] --->v1
        # [1, 2, 3, ['a', 'b', 'c']]
        #v1的第二层列表(子对象改变后) v3也跟着改变
        print(v1[3] is v3[3])  #True
        ===>v1[3] 和v3[3]指向同一个内存地址
        ===>浅拷贝只会拷贝到父对象 不会拷贝到子对象
        
        #2.深拷贝
        
        v1=[1,2,3,["a","b"]]
        import copy
        v4=copy.deepcopy(v1)
        print(v4 is v1)#False
        v1.append("Gao")#v1改变
        print(v4)
        #[1, 2, 3, ['a', 'b']] 没改变
        v1[3].append("c")
        print(v4)
        #[1, 2, 3, ['a', 'b']] 没改变
        print(v1[3] is v4[3])#False
        ====>深拷贝会拷贝到所有嵌套的子对象
        
        #3.
        import copy
        v1 = [1,2,3,{"name":'gao',"numbers":[7,77,88]},4,5]
        v2 = copy.deepcopy(v1)
        
        print(v1 is v2)#False
        print(v1[0] is v2[0])#True
        print(v1[3] is v2[3])#False
        print(v1[3]['name'] is v2[3]['name'])#True
        print(v1[3]['numbers'] is v2[3]['numbers'])#False
        print(v1[3]['numbers'][1] is v2[3]['numbers'][1])#True
        
        
        
        
        
        
    • 特殊: tuple是不可变类型,但是嵌套的元组深拷贝也会有效

      v1=(1,2,3,4)
      v2=copy.copy(v1)
      print(id(v1),id(v2))#一样
      
      v2=copy.deepcopy(v1)
      print(id(v1),id(v2))#一样
      
      v1=(1,2,3,4,[1,2,3])
       v2=copy.copy(v1)
      print(id(v1),id(v2))#一样
      
      v2=copy.deepcopy(v1)
      print(id(v1),id(v2))#不一样
      
      
    • 练习

      v1=[1,2,3]
      v2=copu.copy(v1)
      print(v1 ==v2)#一样
      print(v1 is v2)#不同
      print(v1[0] is v2[0])#一样
      
      
      v1=[1,2,3,{'k1':'1':'k2':'2'}]
      v2=copy.deepcopy(v1)
      print(v1 == v2)#一样
      print(v1 is v2)#不同
      print(v1[0] is v2[0])#一样
      print(v1[3] is v2[3])#不同
      

    文件操作(open/read/write/close)

      1. 关闭

    总结

    1. 深浅拷贝

      • 不可变类型

        • 深浅拷贝后,内存地址本该不等 ,但是由于 (小数据缓存机制原因), , (内存地址和value值都相等),(元组tuple的深拷贝除外)
      • 可变类型

        • 浅拷贝(copy):只会拷贝第一层父对象,嵌套的子对象不会被拷贝,即就是如果嵌套的是(列表/集合/字典)只会拷贝到此类对象的引用地址,而不会深入拷贝地址中的存储值

        • 深拷贝(deepcopy):会拷贝到所有嵌套的子对象,(拷贝到不可变类型为止)

          ​ 所以拷贝的和被拷贝对象中的可变类型的内存地址都不相等

      • 特殊:tuple

        • 浅拷贝:内存地址不变
        • 深拷贝:会按照深拷贝原理
    2. 文件操作

      • 打开文件 :open("文件路径","mode=r/w/a",encoding="utf-8")
        • 打开模式 mode
          1. r
          2. w:打开文件之前会清空
          3. a
          4. r+
          5. w+
          6. a+
        • seek(2):光标位置向后移动两个字节
        • 读写追加都会根据不同的打开文件模式来自动改变光标位置
      • 操作
          • read()
          • readline()
          • readlines()
        1. 写:write
        2. 关闭:close()
      • 练习
        • 去换行 strip()
  • 相关阅读:
    Rabbitmq
    eclipse查看源码
    winSCP:无权访问
    jdk1.8.0环境变量设置
    【Linux】开放指定端口设置
    Redis (windows)安装
    [转]Windows8下设置VS默认启动方式为管理员启动
    [转]varchar(n),nvarchar(n) 长度、性能、及所占空间分析
    [转]Linq中GroupBy方法的使用总结
    [转]人人网首页拖拽上传详解(HTML5 Drag&Drop、FileReader API、formdata)
  • 原文地址:https://www.cnblogs.com/koukouku/p/10679204.html
Copyright © 2020-2023  润新知