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. Python+selenium之测试报告(2)

    # -*- coding: utf-8 -*- import HTMLTestReport import HTMLTestRunner import os import sys import time ...

  2. Nginx FastCGI PHP

    We can see this comment in nginx.conf. # pass the PHP scripts to FastCGI server listening on 127.0.0 ...

  3. 检查EXE、DLL、SYS等文件是32位还是64位的

    非.NET文件用:dumpbin.exe /headers file.exe(C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin) . ...

  4. acid (数据库事务正确执行的四个基本要素的缩写)

    ACID,指数据库事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability).一个支持事务(T ...

  5. Java Marker Interface

    先看看什么是标记接口?标记接口有时也叫标签接口(Tag interface),即接口不包含任何方法. 在Java里很容易找到标记接口的例子,比如JDK里的Serializable接口就是一个标记接口. ...

  6. 常用的CSS居中方式

    1.水平居中margin 0 auto;(浮动元素除外) 这个属性在网页制作的过程中是经常被用到的,一般情况下页面的版心你就可以看到它. <style> .father { width: ...

  7. webpack4 + vue多页面项目精细构建思路

    #构建思路 虽然当前前端项目多以单页面为主,但多页面也并非一无是处,在一些情况下也是有用武之地的,比如: 项目庞大,各个业务模块需要解耦 SEO更容易优化 没有复杂的状态管理问题 可以实现页面单独上线 ...

  8. 关于UINavigationController的一些技巧

    未自定义任何东西的导航条效果如下: 1.自定义了 leftBarButtonItem 之后,左滑返回手势失效了,解决办法: self.navigationController.interactiveP ...

  9. NSURL初始化失败

    服务端给返回的网页加载不出来,仔细一看,url是空的!!为什么呢. 示例: NSString *urlStr = @"http://服务器返回带有汉字的url字符串.com"; N ...

  10. 【线段树合并】bzoj3545: [ONTAK2010]Peaks

    1A还行 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问, ...