问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

copy --- 浅层 (shallow) 和深层 (deep) 复制操作

发布网友 发布时间:2022-12-05 19:38

我来回答

1个回答

热心网友 时间:2024-11-29 22:29

copy --- 浅层 (shallow) 和深层 (deep) 复制操作

Python 中赋值语句不复制对象,而是在目标和对象之间创建绑定 (bindings) 关系。对于自身可变或者包含可变项的集合对象,开发者有时会需要生成其副本用于改变操作,进而避免改变原对象。

直接赋值: 其实就是对象的引用(别名)。

浅拷贝(copy): 拷贝父对象,不会拷贝对象的内部的子对象。

深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

copy模块提供了通用的浅层复制和深层复制操作的方法。

copy.copy( x )返回 x 的浅层复制。

copy.deepcopy( x [, memo ])返回 x 的深层复制。

exception  copy.error针对模块特定错误引发。

浅层复制和深层复制之间的区别仅与复合对象 (即包含其他对象的对象,如列表或类的实例) 相关:

一个 浅层复制 会构造一个新的复合对象,然后(在可能的范围内)将原对象中找到的 引用 插入其中。

一个 深层复制 会构造一个新的复合对象,然后递归地将原始对象中所找到的对象的 副本 插入。

深层复制操作通常存在浅层复制操作不存在的两个问题:

递归对象 (直接或间接包含对自身引用的复合对象) 可能会导致递归循环。

由于深层复制会复制所有内容,因此可能会过多复制(例如本应该在副本之间共享的数据)。

deepcopy()函数避免通过以下方法这些问题:

保留在当前复制过程中已复制的对象的 "备忘录" (memo) 字典;

允许用户定义的类重载复制操作或复制的组件集合。

该模块不复制模块、方法、栈追踪(stack trace)、栈帧(stack frame)、文件、套接字、窗口、数组以及任何类似的类型。它通过不改变地返回原始对象来(浅层或深层地)“复制”函数和类。

制作字典的浅层复制可以使用 dict.copy() 方法,而制作列表的浅层复制可以通过复制整个列表的切片完成,例如,copied_list = original_list[:]。

类可以使用与控制序列化(pickling)操作相同的接口来控制复制操作,关于这些方法的描述信息请参考 pickle 模块。实际上,copy模块使用的正是从 copyreg 模块中注册的 pickle 函数。

想要给一个类定义它自己的拷贝操作实现,可以通过定义特殊方法__copy__()和__deepcopy__()。 调用前者以实现浅层拷贝操作,该方法不用传入额外参数。

调用后者以实现深层拷贝操作——它应传入一个参数即memo字典。 如果__deepcopy__()实现需要创建一个组件的深层拷贝,它应当调用 deepcopy() 函数并以该组件作为第一个参数,而将 memo 字典作为第二个参数。

下面我们通过例子来深入理解

字典浅拷贝实例

#浅拷贝可以导入copy也可以不导入>>>a = {1: [1,2,3]}>>> b = a.copy()>>> a, b({1: [1,2,3]}, {1: [1,2,3]})>>> a[1].append(4)>>> a, b({1: [1,2,3,4]}, {1: [1,2,3,4]})

字典深拷贝实例

#深度拷贝必须导入copy模块>>>importcopy>>> c = copy.deepcopy(a)>>> a, c({1: [1,2,3,4]}, {1: [1,2,3,4]})>>> a[1].append(5)>>> a, c({1: [1,2,3,4,5]}, {1: [1,2,3,4]})

解析

1、 b = a:: 赋值引用,a 和 b 都指向同一个对象。



2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。



b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。



更多实例(列表)

以下实例是使用 copy 模块的 copy.copy( 浅拷贝 )和(copy.deepcopy ):

#!/usr/bin/python# -*-coding:utf-8 -*-importcopya = [1,2,3,4, ['a','b']]#原始对象b = a#赋值,传对象的引用c = copy.copy(a)#对象拷贝,浅拷贝d = copy.deepcopy(a)#对象拷贝,深拷贝a.append(5)#修改对象aa[4].append('c')#修改对象a中的['a', 'b']列表对象print('a = ', a )print('b = ', b )print('c = ', c )print('d = ', d )

以上实例执行输出结果为:

('a = ', [1,2,3,4, ['a','b','c'],5])('b = ', [1,2,3,4, ['a','b','c'],5])('c = ', [1,2,3,4, ['a','b','c']])('d = ', [1,2,3,4, ['a','b']])
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
南安椎间盘突出症的症状,悬壶邱腰神在陕西哪里 安康腰椎间盘突出一条腿麻保守治疗的方法,悬壶邱大夫的详细位置_百度知 ... 宣传片拍摄有哪些长处? 继承房产过户费用要多少? 继承5万房产过户需要多少费用多少钱 继承的房产过户需要多少费用 继承5万房产过户需要多少费用 灵芝茶减肥效果怎么样 南京滴滴和t3哪个收入多 属虎女人的和属鸡男人的配吗 19款威驰自动挡不带天窗跑了6000公里现在能卖多少钱? 19款丰田威驰手动挡1.5油耗 2021款威驰落地价 19款威驰落地多少钱 求一份化工方面的生产工艺设计合同 如何不用电脑打开开发者模式iphone 百越课堂怎么解除合约 培飞在上海有几家校区?徐汇区有吗? 毛豆的种植方法和时间 如何种植毛豆 华为荣耀20青春版怎么录屏 谷丙转氨酶79谷酰胺转移酶239 谷丙转氨酶中度增高、谷氨酰转肽酶轻度增高高血脂 今天检查,谷丙转氨酶63 正常值0-42 谷酰转氨酶97 正常值7-50;磷1.4... 谷丙转氨酶和谷酰转肽酶偏高是怎么治疗 我想问一下丙氨酰谷氨酰胺和脂肪乳的临床区别是什么? 苯谷胺的合成 海尔ES50H-Z3 (ME)电热水器 怎么使用3D加热功能具体一点谢谢 for的原形形式是什么? 羽绒服破了个小洞怎么修补 羽绒服破洞可以干洗吗 换一个志骏发动机水管三通多少钱 猫咪为什么要把便便埋起来 猫咪埋屎埋十几分钟 问一下手机尾号豹子333好不好? 仙人掌可以去痘痘 仙人掌有去痘痘的效果吗 能消痘痘的植物 半枝莲和半边莲煲猪廋肉可以去痘痘吗? 汽车倒车镜上的小镜子怎么安装? 立冬的习俗是什么? 怎么破解长城笔记本电脑开机密码? 中交兴路柴油卡利弊 中石化柴油联名卡,不是申请单位挂靠的车辆可以申请吗? ps怎么把地毯放倒在画布上 碘油造影在临床上有什么意义? 碘油造影的术后注意 2022年10月24日北京到大厂通车了吗? 武汉地铁5期规划什么时候确定 浦东东三里桥路160弄13号坐几号地铁到那里 从八佰伴到东山里桥路160弄20号开车多久 普陀区离浦东三里桥怎么走 从东八里去唐山工业学院怎么走