可变对象和不可变对象

了解深拷贝和浅拷贝之前你得先知道什么时可变对象什么是不可变对象传送门


深拷贝和浅拷贝拷贝不可变对象时

import copy
a = 1
b = copy.copy(a)
c = copy.deepcopy(a)
print(id(a))
print(id(b))
print(id(c)

输出结果

140714631783056
140714631783056
140714631783056

当深拷贝和浅拷贝拷贝可变对象时

a = [1,2]b = copy.copy(a)
c = copy.deepcopy(a)
a.append(3)
print(a)
print(b)
print(c)
print(id(a))
print(id(b))
print(id(c))

输出结果:

[1, 2, 3]
[1, 2]
[1, 2]
2161196250376
2161196250248
2161196250632

不管深拷贝还是浅拷贝对不可变数据类型都是引用内存地址
不管深拷贝还是浅拷贝对可变数据类型都是会重新创建新的内存空间


浅拷贝嵌套对象

# -----------不可变数据类型---------
# 情况一,内嵌可变数据类型
import copy
a = ([1,2],(3,4))  # 不可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a))  # 内存地址相同
# 情况二,内嵌不可变数据类型
a = ((1,2),(3,4))  # 不可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a))  # 内存地址相同#-----------可变数据类型-------------
# 情况一,内嵌可变数据类型
import copy
a = [(1,2),[3,4]]  # 可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a))  # 内存地址不相同# 情况一, 可变数据类型 内嵌可变数据类型
import copy
a = [(1,2),(3,4)]  # 可变数据类型
copy_a = copy.copy(a)
print(id(a),id(copy_a))  # 内存地址不相同
import copya = [1,2,[3,4]]b = copy.copy(a)
print(a)
print(b)
print(id(a))
print(id(b))a[2].append(5)
print(a)
print(b)
print(id(a))
print(id(b))

输出结果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
2879593821128
2879593821512
[1, 2, [3, 4, 5]]
[1, 2, [3, 4, 5]]
2879593821128
2879593821512     # 内存地址虽然不一样,但是当a的顶层的数据发生了变化   b的顶层的数据也发生了变化

深拷贝嵌套对象

# -----------不可变数据类型---------
# 情况一,内嵌可变数据类型
import copy
a = ([1,2],(3,4))  # 不可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a))  # 内存地址不相同
# 情况二,内嵌不可变数据类型
a = ((1,2),(3,4))  # 不可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a))  # 内存地址相同#-----------可变数据类型-------------
# 情况一,内嵌可变数据类型
import copy
a = [(1,2),[3,4]]  # 可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a))  # 内存地址不相同
print(id(a[0]),id(copy_a[0]))  # 内存地址相同
print(id(a[1]),id(copy_a[1]))  # 内存地址不相同# 情况一, 可变数据类型 内嵌可变数据类型
import copy
a = [(1,2),(3,4)]  # 可变数据类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a))  # 内存地址不相同
print(id(a[0]),id(copy_a[0]))  # 内存地址相同
a = [1,2,[3,4]]b = copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))a[2].append(5)
print(a)
print(b)
print(id(a))
print(id(b))

输出结果:

[1, 2, [3, 4]]
[1, 2, [3, 4]]
2049726264200
2049726264584
[1, 2, [3, 4, 5]]
[1, 2, [3, 4]]
2049726264200   # 这时候和浅拷贝不一样了哦,虽然a的顶层的数据发生了变化,但是b还是未发生变化
2049726264584

浅拷贝:

外层是不可变类型、不管内层是否可变都是引用拷贝
外层是可变类型,不管内层是否可变都会从新创建新的内存空间
当拷贝另一个对象后,顶层的数据时引用原对象的,所以原对象的顶层数据发生改变,拷贝的也会发生改变

深拷贝:

外层是不可变类型,会递归判断内层数据类型、如果可变则创建新的内存地址、都为不可变就是引用拷贝
外层是可变数据类型、不管内层是否可变都会创新新的内存地址、但是内部如果为可变则递归创建、不可变则为引用地址
面对可变对象的时候就相当于时将a完全拷贝到一个新的内存地址

总结

浅拷贝

浅拷贝只做最顶层的数据类型判断
如果顶层是可变类型则创建新的内存空间
如果顶层是不可变数据类型就是引用拷贝

深拷贝

拷贝做递归拷贝,可以递归拷贝所有的内部嵌套数据(可以理解为循环遍历做浅拷贝判断)
深拷贝递归拷贝遇到可变类型则创建新的内存空间
深拷贝递归拷贝遇到不可变数据类型就是拷贝的引用

参考博客:
https://www.cnblogs.com/fandx/p/10462913.html

关于python中的深拷贝和浅拷贝的总结相关推荐

  1. python怎么避免浅拷贝_详谈Python中的深拷贝和浅拷贝

    在平时工作中,经常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题.为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用.为了生成这个副本,就产生了拷贝. ...

  2. python中的深拷贝与浅拷贝

    浅拷贝的时候,修改原来的对象,深拷贝的对象不会发生改变. 对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷 ...

  3. python中关于深拷贝和浅拷贝的详解

    python中关于深拷贝和浅拷贝的详解 概述 在python的语法中,有两种变量的拷贝方式 一种是深拷贝,一种是浅拷贝 我们先说深拷贝 语法 这里需要通过导入系统的copy模块中的deepcopy才可 ...

  4. python深浅拷贝的底层理解_理解python中的深拷贝与浅拷贝

    python中浅拷贝和深拷贝的区别如下: 1. copy.copy 等价于切片[:]  浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2个列表是不同的,但是子列表指向的仍然是同一个地址 2. co ...

  5. python中深拷贝和浅拷贝_**Python中的深拷贝和浅拷贝详解

    甚至连type其本身都是对象,type对象 Python中变量与C/C++/Java中不同,它是指对象的引用,Python是动态类型,程序运行时候,会根据对象的类型 来确认变量到底是什么类型. 单独赋 ...

  6. python中的引用、浅拷贝和深拷贝

    在python中,有一句话:"一切皆为对象,一切皆为对象的引用",所以 只要记住这句话就很容易清楚python中的引用.浅拷贝和深拷贝了. 1. 引用 python中的引用是经常使 ...

  7. vb.net中递归退到最外层_面试题被问到再也不慌,深究JavaScript中的深拷贝与浅拷贝...

    " 点个关注,养成习惯,带你python爬虫的过程中学习前端 " JavaScript中的深拷贝和浅拷贝是前端面试中频繁被问到的一道题, 于是我也自己去查阅了一些资料, 然后动手敲 ...

  8. C语言中的深拷贝和浅拷贝

    http://www.cnblogs.com/zhanggaofeng/p/5421804.html C语言中的深拷贝和浅拷贝 //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_N ...

  9. js中的深拷贝和浅拷贝区别

    js中的深拷贝和浅拷贝与值传递和引用传递有着些许的关联,都是根据堆栈中数据的储存来传递数据. 下面主要说一下我对深拷贝和浅拷贝的理解: 简单举个例子来说明:当我们声明一个a变量并且赋值,并且让b等于a ...

最新文章

  1. C#用XmlDocument操作XML
  2. 分区报无效的参数_西门子70系列变频器55KW上电就报F002故障维修
  3. map and flatmap 区别
  4. zookeeper安装和使用
  5. 数据源中没有 datarow_Power BI Desktop 中的数据源
  6. 明天开始放假了[2.5-2.13],春节期间计划
  7. android react混合开发框架,7个混合式移动开发框架
  8. 实测python-onvif协议控制摄像头
  9. 10. InnoDB表空间加密
  10. 【最优化方法】K-Means聚类实验:Python实现手写数字图像MNIST分类
  11. 台式计算机调整显示亮度,台式电脑显示器屏幕亮度怎么调节?
  12. 楼市降价潮蔓延至二三线城市 土地多底价成交
  13. CVPR2021 视频目标检测论文推荐
  14. Web安全:白帽子黑客训练营
  15. DCloud之Android平台应用启动时读写手机存储、访问设备信息(如IMEI)等权限策略控制
  16. Google Earth Engine(GEE)对比显示不同城市的地表温度
  17. javase笔记基础篇
  18. 怎么安装aptdaemon模块_dlt-daemon安装教程
  19. 【Luogu】P2465山贼集团(树形状压DP)
  20. js学习笔记--了解promise

热门文章

  1. AE/PR脚本:视频字幕创建导入和导出插件Subtitle Pro
  2. 无心剑英汉双语诗004.《静心》
  3. Reggie外卖项目 —— 分类管理模块之新增分类功能
  4. linux 修改文件明,linux修改文件名你肯定不知道可以这样操作
  5. Java菜鸟面试突破系列之MySQL优化
  6. Unity Shader - Shader常用属性标签(材质属性面板标签)
  7. 再见Python!数据分析可以这样做。
  8. ElasticSearch~ElasticSearch启动成功,但是无法访问
  9. Ansys-施加非法向表面载荷实例-转矩的施加学习收获
  10. R语言检验样本比例:使用prop.test函数执行单样本比例检验计算总体中成功样本比例p值的置信区间