python中深拷贝和浅拷贝,python浅拷贝和深拷贝详解

  python中深拷贝和浅拷贝,python浅拷贝和深拷贝详解

  要弄清楚Python中的明拷贝和暗拷贝,需要理解以下概念:

  可变引用对象(可变对象,不可变对象)-切片复制(轻复制,深复制)

  在Python中一切都是对象。

  甚至类型本身也是一个对象,而类型对象

  Python中的变量不同于C/C /Java中的变量。它指的是一个对象的引用。Python是一种动态类型。程序运行时,会根据对象的类型来确认变量的类型。

  单独分配:例如:

  a=3

  运行a=3后,变量a就变成了对对象3的引用。在内部,变量实际上是一个指向对象内存空间的指针。

  因为Python变量只是对象的引用或者对象的指针,所以变量引用经常可以在程序中改变。

  代码如下:

  X=42 #变量被绑定到一个整数对象。

  X=Hello #现在又是一个字符串了。

  X=[1,2,3] #现在又是列表了。

  专业表达如下:

  *变量是系统表的一个元素,带有连接到对象的空间。

  *对象是一个分配的内存块,用于存储它所代表的值。

  *引用是从变量到对象自动形成的指针。

  *特别说明:类型属于对象,不属于变量。

  例如,就像a=3一样,整数对象3包含两种信息。

  1.该值为3

  2.头消息:告诉Pthyon它是一个整数对象[相当于一个指向int的指针]

  分享:例如:

  代码如下:

  a=3

  b=a

  运行赋值语句b=a后,变量A和变量B指向同一个对象的内存空间。

  从上图可以看出,A和B,id相同,指向同一个integer对象3,或者同一块内存。

  如果A被删除,不会影响b。

  复制概念的引入是针对可变对象共享引用的潜在副作用。

  [可变对象-不可变对象]

  在Python中,不可变对象是指一旦创建就不能修改的对象,包括字符串、祖先和数字。

  在Python中,可变对象是指可以修改的对象,包括列表和字典。

  上面的A和B都是整数。整数是不可变的对象。如果它们是可变对象,那就另当别论了。

  代码如下:

  L1=[2,3,4]# L1 L1变量指向一个可变对象:一个列表

  L2=L1 #将L1值赋给L2后,它们共享并引用同一个列表对象[1,2,3,4]

  L1[0]=200 #因为列表是可变的,所以改变L1中第一个元素的值

  L1;L2 #发生变化后,L1和L2同时发生变化,因为物体本身的价值发生变化。

  [200, 3, 4]

  [200, 3, 4]

  如果你不想改变列表L2的值,有两种方法:切片和复制模块。

  代码如下:

  L1=[2,3,4]

  L2=L1

  id(L1);Id(L2) # Share引用了一个可变对象

  45811784L

  45811784L

  L2=L1[:] #切片操作

  id(L1);Id(L2) #切片后,对象就不一样了。

  45811784L

  45806920L

  L1[0]=200

  L1;L2 #L1变了,L2没变。

  [200, 3, 4]

  [2, 3, 4]

  [副本]

  切片技术适用于所有序列,包括列表、字符串和祖先。

  但是切片不能应用于字典。只有D.copy()方法或D.deepcopy()方法可用于字典。

  复制,可用于序列或字典。

  代码如下:

  导入副本

  X=copy.copy(Y) # light copy:仅复制顶级对象或父对象。

  X=copy.deepcopy(Y) # Deep copy:复制所有对象、顶层对象及其嵌套对象。或者:父对象及其子对象。

  如果字典只有顶级对象:

  如果对象嵌套在字典中:

  [结论]

  深度和深度都复制源对象,占用不同的内存空间。

  如果源对象只有一个一级目录,则源所做的任何更改都不会影响深拷贝和浅拷贝对象。

  如果源对象有多个级别的目录,对源的任何更改都将影响轻型副本,但不会影响深层副本。

  序列的切片实际上是一个浅拷贝,即只拷贝顶层对象。

  直接赋值:实际上是一个对象的引用(别名)。

  复制:复制父对象,但不复制对象的内部子对象。

  复制模块的Deepcopy方法完全复制父对象及其子对象。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: