源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Python中的深拷贝和浅拷贝详解

  • 时间:2020-07-20 04:12 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Python中的深拷贝和浅拷贝详解
要说清楚Python中的深浅拷贝,需要搞清楚下面一系列概念: 变量-引用-对象(可变对象,不可变对象)-切片-拷贝(浅拷贝,深拷贝) [b]【变量-对象-引用】[/b] 在Python中一切都是对象,比如说:3, 3.14, 'Hello', [1,2,3,4],{'a':1}...... [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090150_0_69077.jpg[/img] 甚至连type其本身都是对象,type对象 Python中变量与C/C++/Java中不同,它是指对象的引用,Python是动态类型,程序运行时候,会根据对象的类型 来确认变量到底是什么类型。 单独赋值: 比如说:
[u]复制代码[/u] 代码如下:
>>> a = 3
在运行a=3后,变量a变成了对象3的一个引用。在内部,变量事实上是到对象内存空间的一个指针 [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090150_1_5142.jpg[/img] 因为Python的变量不过是对象的引用,或指向对象的指针,因此在程序中可以经常改变变量引用
[u]复制代码[/u] 代码如下:
>>> x = 42      #变量绑定到整型对象 >>> x = 'Hello' #现在又成了字符串 >>> x = [1,2,3] #现在又成了列表
专业表述如下: 变量是一个系统表的元素,拥有指向对象的连接的空间 对象是被分配的一块内存,存储其所代表的值 引用是自动形成的从变量到对象的指针 特别注意: 类型属于对象,不是变量 比如像刚才的a=3, 整数对象3包含了两重信息 1.值为3 2.一个头部信息:告诉Pthyon,这是个整数对象[相当于一个指向int的指针] 共享引用: 比如说:
[u]复制代码[/u] 代码如下:
>>> a = 3 >>> b = a
在运行赋值语句b = a之后,变量a和变量b指向了同一个对象的内存空间. [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090150_2_85987.jpg[/img] [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090151_3_9440.jpg[/img] 从上图可以看到,a和b,其id完全一样,指向同一个整数对象3,或者说同一块内存 [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090151_4_36851.jpg[/img] 如果删掉a后, 不会影响b [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090152_5_85879.jpg[/img] 拷贝概念的引入就是针对:可变对象的共享引用潜在的副作用而提出的. [b]【可变对象-不可变对象】[/b] 在Python中不可变对象指:一旦创建就不可修改的对象,包括字符串,元祖,数字 在Python中可变对象是指:可以修改的对象,包括:列表、字典 上面说的a,b都是整数,整数是不可变对象,如果是可变对象的话,就是另外一回事了。
[u]复制代码[/u] 代码如下:
>>> L1 = [2,3,4]      #L1变量指向的是一个可变对象:列表  >>> L2 = L1           #将L1值赋给L2后,两者共享引用同一个列表对象[1,2,3,4]  >>> L1[0] = 200       #因为列表可变,改变L1中第一个元素的值  >>> L1; L2            #改变后,L1,L2同时改变,因为对象本身值变了  [200, 3, 4]  [200, 3, 4] 
如果不想改变列表L2的值,有两种方法:切片 和 copy模块
[u]复制代码[/u] 代码如下:
>>> L1 = [2,3,4]   >>> L2 = L1  >>> id(L1);id(L2)     #共享引用一个可变对象  45811784L  45811784L  >>> L2 = L1[:]        #切片操作  >>> id(L1);id(L2)     #切片后,对象就不一样了  45811784L  45806920L  >>> L1[0] = 200  >>> L1;L2             #L1发生改变,L2没有变化  [200, 3, 4]  [2,   3, 4] 
[b]【拷贝】[/b] 1. 切片技术应用于所有的序列,包括:列表、字符串、元祖    >>>但切片不能应用于字典。对字典只能使用D.copy()方法或D.deepcopy()方法. [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090152_6_19626.jpg[/img] 2. 深浅拷贝,即可用于序列,也可用于字典
[u]复制代码[/u] 代码如下:
   >>> import copy    >>> X = copy.copy(Y)      #浅拷贝:只拷贝顶级的对象,或者说:父级对象    >>> X = copy.deepcopy(Y)  #深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象
如果字典只有顶级对象: [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090153_7_37063.jpg[/img] 如果字典中嵌套对象: [img]http://img.1sucai.cn/uploads/article/2018010709/20180107090153_8_28841.jpg[/img] [b]【结论】[/b] 深浅拷贝都是对源对象的复制,占用不同的内存空间 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部