zoukankan      html  css  js  c++  java
  • 关于Python深浅拷贝

    拷贝:

      说明原则上就是把数据分离出来,复制其数据,并以后修改互不影响。

    何来深浅拷贝的说法?

      深浅拷贝的“深”和“浅”可以理解为从变量到硬盘上的物理存储介质之间的层次的多少。

     

    下面用一个示例来解释浅拷贝:

     1 #Author : Kelvin
     2 #Date : 2019/1/5 0:41
     3 import copy
     4 #浅拷贝的第一种方式(使用对象自身的copy方法)
     5 li1=[["bob","alvin"],"kelvin","alex"]
     6 li2=li1.copy() #调用列表自身方法拷贝
     7 li2[1]="kelvin-sb"  #修改li2的第二个元素
     8 print("li1: ",li1)
     9 print("li2: ",li2)
    10 #运行结果(只有li2改变了):
    11 #li1:  [['bob', 'alvin'], 'kelvin', 'alex']
    12 # li2:  [['bob', 'alvin'], 'kelvin-sb', 'alex']
    13 print("-------"*6)
    14 li2[0][0]="bob-sb"  #修改li2的第一个元素中的第一个元素
    15 print("li1: ",li1)
    16 print("li2: ",li2)
    17 #运行结果(li1和li2都改变了):
    18 # li1:  [['bob-sb', 'alvin'], 'kelvin', 'alex']
    19 # li2:  [['bob-sb', 'alvin'], 'kelvin-sb', 'alex']
    20 
    21 
    22 
    23 
    24 
    25 #浅拷贝的第二种方式(使用copy模块的copy方法)
    26 li1=[["bob","alvin"],"kelvin","alex"]
    27 li2=copy.copy(li1) #调用copy模块方法拷贝
    28 li2[1]="kelvin-sb"  #修改li2的第二个元素
    29 print("li1: ",li1)
    30 print("li2: ",li2)
    31 #运行结果(只有li2改变了):
    32 #li1:  [['bob', 'alvin'], 'kelvin', 'alex']
    33 # li2:  [['bob', 'alvin'], 'kelvin-sb', 'alex']
    34 print("-------"*6)
    35 li2[0][0]="bob-sb"  #修改li2的第一个元素中的第一个元素
    36 print("li1: ",li1)
    37 print("li2: ",li2)
    38 #运行结果(li1和li2都改变了):
    39 # li1:  [['bob-sb', 'alvin'], 'kelvin', 'alex']
    40 # li2:  [['bob-sb', 'alvin'], 'kelvin-sb', 'alex']

    对于上面浅拷贝的示例我们可以看到,当浅拷贝之后,修改其中一个不可变类型元素(数字,字符串等),拷贝前后对象之间互不干扰,没有影响,但是当修改了可变类型元素(列表,字典等),拷贝前后对象均发生改变。其中的原因就是因为不可变类型直接存储在物理硬盘上,而可变类型则会包含多个不可变类型而形成一个独立的内存地址,也就是多了一“层”。下面用图示具体说明:

      只改变“kelvin”图示:

      改变li1第一个元素(列表)中的值图示:

    **注:认真理清图示表达的含义,理解好深浅的内涵。

      

      下面再通过一个示例来了解深拷贝:

     1 import copy
     2 #深拷贝只能调用copy模块的deepcopy方法
     3 li1=[["bob","alvin"],"kelvin","alex"]
     4 li2=copy.deepcopy(li1) #调用copy模块方法拷贝
     5 li2[1]="kelvin-sb"  #修改li2的第二个元素
     6 print("li1: ",li1)
     7 print("li2: ",li2)
     8 #运行结果(只有li2改变了):
     9 #li1:  [['bob', 'alvin'], 'kelvin', 'alex']
    10 # li2:  [['bob', 'alvin'], 'kelvin-sb', 'alex']
    11 print("-------"*6)
    12 li2[0][0]="bob-sb"  #修改li2的第一个元素中的第一个元素
    13 print("li1: ",li1)
    14 print("li2: ",li2)
    15 #运行结果(只有li2改变了):
    16 # li1:  [['bob', 'alvin'], 'kelvin', 'alex']
    17 # li2:  [['bob-sb', 'alvin'], 'kelvin-sb', 'alex']

      深拷贝相比较浅拷贝就容易理解的多,因为深拷贝就是完完全全的拷贝,拷贝前后的两个对象占有独立的内存空间,不存在共享空间,因此拷贝前后对象相互改变无影响。

    最后来一个深浅拷贝的应用实例(随意实例):

     1 #Author : Kelvin
     2 #Date : 2019/1/5 1:37
     3 
     4 import copy
     5 kelvin=["kelvin",123,[10000,]] #户主  卡号  余额
     6 wife=kelvin.copy()  #给媳妇共享银行卡
     7 wife[1]=234 #设置媳妇卡号
     8 wife[0]="peiqi" #媳妇银行卡户主
     9 wife[2][0]-=2000 #媳妇消费2000元
    10 print(kelvin)
    11 print(wife)
    12 print("------"*6)
    13 # 输出结果(实现共享账户):
    14 # ['kelvin', 123, [8000]]
    15 # ['peiqi', 234, [8000]]
    16 
    17 
    18 #小三账户不能浅拷贝,因为媳妇会发现账户少钱
    19 xiaosan=copy.deepcopy(kelvin)
    20 xiaosan[0]="sanzi" #小三银行卡户主
    21 xiaosan[1]=666 #设置小三卡号
    22 xiaosan[2][0]-=3000 #小三消费3000元
    23 print(kelvin)
    24 print(xiaosan)
    25 # 输出结果(老婆不会发现):
    26 # ['kelvin', 123, [10000]]
    27 # ['sanzi', 666, [7000]]
  • 相关阅读:
    画笔
    进程和线程<二>
    进程和线程<一>
    文件<2>
    文件<1>
    窗口(3)
    窗口<二>
    窗口(1)
    消息
    位图
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/10223221.html
Copyright © 2011-2022 走看看