深浅拷贝的原理


深浅拷贝用法来自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. 【转】MySQL数据类型

    1.整型 MySQL数据类型 含义(有符号) tinyint(m) 1个字节  范围(-128~127) smallint(m) 2个字节  范围(-32768~32767) mediumint(m) ...

  2. FastReport.Net 无限页高(连续纸小票)

    using System; using System.Collections; using System.Collections.Generic; using System.ComponentMode ...

  3. java 两个数组合并

    需求:两个字符串合并(如果想去重复,参考下一篇--数组去重复及记录重复个数) //方法一 Arrays类 String[] a = {"A","B"," ...

  4. SQL的拼接语句在DELPHI中怎么写

    SQL 语句的拼接,关键点在于对引号的处理上. 在 delphi 的语法中,使用单引号做字符串的标志符.因此,当遇到 SQL 语句中字符串标识量编写的时候,需要用两个单引号来代替实际的引号. 举例: ...

  5. HDU4787_GRE Words Revenge

    这个题目做得泪牛满面. 题目为给你若干串,有的表示添加一个串,有的表示询问一个串有多少个字串为前面出现过的串. 题目一看就知道肯定是AC自动机(不过后缀自动机也是可以的) 但是细想就会发现AC自动机好 ...

  6. 苹果手机连wifi跳不出来登录网页解决办法

    1.点开要连接wifi后面的小叹号“!”,打开“自动登录” 2.打开设置,关闭SAFARI的“阻止弹窗” 3.重新连接wifi

  7. (转)rabbitmq的web管理界面无法使用guest用户登录

    转至http://www.cnblogs.com/mingaixin/p/4134920.html 安装最新版本的rabbitmq(3.3.1),并启用management plugin后,使用默认的 ...

  8. Qt浅谈内存泄露(总结)

    Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...

  9. oracle 时间

    select to_char(to_date(sysdate,'yyyy-mm-dd'),'day') from dual; select to_date('2017-12-31','day') fr ...

  10. java根据系统生成临时文件

    createTempFile 会根据当前系统,自动找系统的临时文件目录,在此目录下生成临时文件