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

深浅拷贝的原理


深浅拷贝用法来自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仅仅将最外层的内容在内存中新建了一份出来,字典第二层的列表并没有在内存中新建,所以你修改了新模版,默认模版也被修改了。

本文转载自:https://www.cnblogs.com/zhuifeng-mayi/p/9179647.html

Python的深浅copy的更多相关文章

  1. Python的深浅copy详解

    Python的深浅copy详解 目录 Python的深浅copy详解 一.浅copy的原理 1.1 浅copy的定义 1.2 浅copy的方法 二.深copy的原理 2.1 深copy的定义 2.2 ...

  2. Python 集合 深浅copy

    一,集合. 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. ...

  3. python集合深浅copy

    一,集合. 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. ...

  4. Python之深浅copy与字符编码

    一.深浅copy 1. 首先看赋值运算 l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['barr ...

  5. python之深浅copy

    深浅copy 1.赋值运算 a = [1, 2, 3] b = a a.append(666) print(b) #output:[1, 2, 3, 666] 对于赋值运算来说,a与b指向的是同一个内 ...

  6. 【python】-- 深浅copy、集合

    深浅copy 1.数字.字符串的copy: 赋值(=).浅拷贝(copy)和深拷贝(deepcopy)其实都一样,因为它们永远指向同一个内存地址: >>> import copy & ...

  7. python基础--深浅copy(重点)

    在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 深浅copy(重点) 先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单 ...

  8. day python calss08 深浅copy

    一  join (格式:   . join) 遍历列表把列表中的每一项用指定符号进行拼接.(把列表转成字符串0 # lst = ["汪峰", "吴君如", &q ...

  9. python 的深浅copy

    1.引用: A=B, 修改B后,A会被修改 2.浅拷贝:A=copy.copy(B) 3.深拷贝:A=copy.deepcopy(B) 如果希望任何改变,两个对象都不会相互影响,用深拷贝.详情参考:h ...

随机推荐

  1. springBoot jpa 表单关联查询

    1.创建两个实体类 import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.per ...

  2. background-size在IE8不兼容问题

    background-size在IE8及以下浏览器不兼容:要解决的话要用滤镜: filter: progid: DXImageTransform.Microsoft.AlphaImageLoader( ...

  3. vim的命令

    下面是从一个博客里摘抄出来的, 供自己学习使用.   在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行.你可以试试把代码缩进任意打乱再用n= ...

  4. Layer:如何调用layer.open打开的的iframe窗口中的JS?

    layer.open({type: 2,content: 'test/iframe.html',success: function(layero, index){ var body = layer.g ...

  5. 如何正确配置 Nginx + PHP ???

    本文转自如何正确配置 Nginx + PHP,如有侵权,请联系管理员及时删除!

  6. SharePoint 2016 功能比较

    SharePoint 2016中有很多功能.我们经常和客户谈论SharePoint安装时,我问他们是否计划安装SharePoint Server 2016 Standard或Enterprise.通常 ...

  7. VB SMTP用户验证发送mail

    转自 http://www.jishuzh.com/program/vb-smtp%E7%94%A8%E6%88%B7%E9%AA%8C%E8%AF%81%E5%8F%91%E9%80%81mail. ...

  8. HDU 4738 Caocao's Bridges taijan (求割边,神坑)

    神坑题.这题的坑点有1.判断连通,2.有重边,3.至少要有一个人背*** 因为有重边,tarjan的时候不能用子结点和父节点来判断是不是树边的二次访问,所以我的采用用前向星存边编号的奇偶性关系,用^1 ...

  9. Vector 容器简单介绍

    # Vector STL简要介绍 关于STL中的vector容器,以下做一些相关介绍. #### vector 简要概述 vector 称作向量类,属于容器类,实现了动态的数组,用于元素数量变化的对象 ...

  10. NPM下载模块包说明

    博主对npm包安装收集了各种资料和实践后对它们之间的差异整理,写下这篇文章避免自己忘记,同时也给node.js猿友一点指引. 我们在使用 npm install 安装模块的模块的时候 ,一般会使用下面 ...