今日概要

  • 深淺拷貝(重點)
  • 文件操作

詳細內容

  • 直接賦值: 直接將對象的引用賦值給另一個對象

    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()