深浅拷贝的原理


深浅拷贝用法来自copy模块。

导入模块:import copy

浅拷贝:copy.copy

深拷贝:copy.deepcopy

字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据深拷贝指拷贝数据集合的所有层。所以对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等.

对于以下数据深浅拷贝的意义是一样的(因为数据类型中只有一层):

name = 'beijing'   #字符串
age = 12 #数字
list1 = [1,2,3,4] #列表
dic1 = {'name':'beijing','age':20} #字典

从内存地址来理解深浅拷贝:

深浅拷贝:

  字符串,数字的深浅拷贝

>>> import copy
>>> name="hahah" #字符串
>>> name1=copy.copy(name)
>>>
>>> name2=copy.deepcopy(name)
>>> print(id(name),id(name1),id(name2))
11577192 11577192 11577192 >>> sum=111 #数字
>>> sum1=copy.copy(sum)
>>>
>>> sum2=copy.deepcopy(sum)
>>> print(id(sum),id(sum1),id(sum2))
503865568 503865568 503865568

如上图,对于数字和字符串的深浅拷贝都只是将变量的索引指向了原来的内存地址,例如在sum,sum1,sum2三个变量中,无论修改任意其中一个变量,只是将其指向了另一个内存地址,其他两个变量不会变,字符串同理。因此,对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。

  字典(列表)的深浅拷贝

  赋值:

import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n2 = n1

  浅拷贝:

import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n3 = copy.copy(n1)

  深拷贝:

import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n4 = copy.deepcopy(n1)

深浅拷贝的应用场景


  比如在CMDB系统中,我们定义了一个报警模版call给所有的服务器使用,此时有一批特殊应用的服务器需要不通的报警参数,我们既不想单独新建模版来一个一个添加报警参数,又不想修改默认模版而影响其他机器的报警阈值。此时我们就需要用深拷贝来完成。示例如下:

  默认模版:

call = {
'cpu':80,
'mem':80,
'disk':80
}

此时的特殊模版需求是cpu报警阀值要改成75,而不影响默认模版使用

代码如下:

import copy
#默认模版
call = {
'cpu':[80,],
'mem':[80,],
'disk':[80,]
} #新模板
new_call = copy.deepcopy(call)
#修改新模版
new_call['cpu'] = 75
#查看新旧模版的值
print('新的模版为:%s' %(new_call))
print('默认模版为:%s' %(call)) #打印结果:
#新的模版为:{'mem': 80, 'disk': 80, 'cpu': 75}
#默认模版为:{'mem': 80, 'disk': 80, 'cpu': 80} #上面的代码显示我们只改了新的模版,而默认模版并没有修改,并且我们用了copy而不是单独新建模版。

假设我们用浅copy来做结果是这样的:

import copy
#默认模版
call = {
'cpu':[80,],
'mem':[80,],
'disk':[80,]
} #新模板
new_call = copy.copy(call)
#修改新模版
new_call['cpu'] = 75
#查看新旧模版的值
print('新的模版为:%s' %(new_call))
print('默认模版为:%s' %(call))
#打印的结果:
#新的模版为:{'mem': [80], 'disk': [80], 'cpu': [75]}
#默认模版为:{'mem': [80], 'disk': [80], 'cpu': [75]} #默认模版和新模版都被修改了,显然这不是我们要的结果

分析原因:深拷贝的时候python将字典的所有数据在内存中新建了一份,所以如果你修改新的模版的时候老模版不会变。相反,在浅copy 的时候,python仅仅将最外层的内容在内存中新建了一份出来,字典第二层的列表并没有在内存中新建,所以你修改了新模版,默认模版也被修改了。

 

24、简述Python的深浅拷贝以及应用场景的更多相关文章

  1. 简述Python的深浅拷贝以及应用场景

    深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...

  2. 简述Python的深浅拷贝以及应用场景?

    浅拷贝:copy.copy                       深拷贝:copy.deepcopy 浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层 主要应用在字符串,数字的 ...

  3. Python原理 -- 深浅拷贝

    python原理 -- 深浅拷贝 从数据类型说开去 str, num : 一次性创建, 不能被修改, 修改即是再创建. list,tuple,dict,set : 链表,当前元素记录, 下一个元素的位 ...

  4. Python的深浅拷贝

    Python的深浅拷贝 深浅拷贝 1. 赋值,对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量并不是复制一份内容 list1 = [']] list2 = list1 p ...

  5. Python入门-深浅拷贝

    首先我们在这里先补充一下基础数据类型的一些知识: 一.循环删除 1.前面我们学了列表,字典和集合的一些操作方法:增删改查,现在我们来看一下这个问题: 有这样一个列表: lst = ['周杰伦','周润 ...

  6. day2学python 数据类型+深浅拷贝+循环

    数据类型+深浅拷贝+循环 别的语言的数组 python不用定义 直接使用 color=['红','橙','黄','绿','青','蓝','紫'] print(color[1:3]) //打印[1,3) ...

  7. python 赋值 深浅拷贝

    深浅拷贝 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 impor ...

  8. Python随笔---深浅拷贝

    Python中为了避免某些方法的副作用(拷贝后有时更改原有数据),故存在有深浅拷贝的存在 浅拷贝导入copy方法集,使用copy_copy的方法进行 深拷贝一样导入copy方法集,使用copy_dee ...

  9. python 的深浅拷贝问题

    深浅拷贝概念 基本类型和引用类型数据拷贝的问题.因为基本类型的数据大小是固定的,所以他保存在栈内存中:而引用类型的数据大小不固定,因而保存在堆内存中,单引用类型在栈内存中只保存一个指向堆内存的指针. ...

随机推荐

  1. workstation vmware 制作vm模板

    [root@VM166136 ~]# cat copy_vmware.sh #!/bin/bash if [ $(id -u) -ne 0 ];then echo "Please use t ...

  2. Oracle数据库表空间常用操作

    1. 查看所有表空间大小 SQL> select tablespace_name,sum(bytes)/1024/1024 from dba_data_files group by tables ...

  3. mysql项目路径URL编码

    jdbc_url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useUnicode=true&characterEncodi ...

  4. hdu-题目1421:搬寝室

    http://acm.hdu.edu.cn/showproblem.php?pid=1421 搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  5. 采用FPGA实现UART转SPI

    应用笔记 V1.1 2015/2/10 采用FPGA实现UART转SPI   概述   本文提供了实现UART转SPI的Verilog代码的功能描述.这份笔记将介绍UART和SPI的基本知识,代码设计 ...

  6. 第91天:CSS3 属性选择器、伪类选择器和伪元素选择器

    一.属性选择器 其特点是通过属性来选择元素,具体有以下5种形式: 1.E[attr] 表示存在attr属性即可:    div[class] 2.E[attr=val] 表示属性值完全等于val:   ...

  7. hbase快速入门

    hbase 是什么? Apache HBase is an open-source, distributed, versioned, non-relational database modeled a ...

  8. BZOJ 2039 人员雇佣(最小割)

    最小割的建图模式一般是,先算出总收益,然后再通过网络模型进行割边减去部分权值. 然后我们需要思考什么才能带来收益,什么才能有权值冲突. s连向选的点,t连向不选的点,那么收益的减少量应该就是将s集和t ...

  9. 学Python Django学得很迷茫,怎么办?-转自知乎

    本人学生,零编程基础,在学习python的过程中越学越迷茫,感觉像无头苍蝇一样,来知乎取经,下面进入正题吧:        我是先看了中谷的python教学视频,然后跟着慕课网上的python教程把题 ...

  10. WlanGetAvailableNetworkList

    原文msdn链接地址:https://docs.microsoft.com/zh-cn/windows/desktop/api/wlanapi/nf-wlanapi-wlangetavailablen ...