在理解深浅拷贝之前,我们先熟悉下变量对象和数据类型
1.变量和对象
变量-引用-对象(可变对象,不可变对象)
在python中一切都是对象,比如[1,2],'hello world',123,{'k1':'v1'},
比如说:
>>> a = 3
专业表述如下:
变量是一个系统表的元素,拥有指向对象的连接的空间
对象是被分配的一块内存,存储其所代表的值
引用是自动形成的从变量到对象的指针
特别注意: 类型属于对象,不是变量
共享引用: 比如说:
>>> a = 3
>>> b = a
在运行赋值语句b = a之后,变量a和变量b指向了同一个对象的内存空间.
2.数据类型
在python中数据类型包括:int,bool,float,str,dict,tuble,set,list等等,
 首先,我们需要知道在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据类型:列表list和字典dict;不可变数据类型:整型int、浮点型float、字符串型string和元组tuple。
用一句话来概括上述过程就是:“python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
3.对于数字和字符串来说,无论通过赋值,浅拷贝还是深拷贝,同一个值永远用的是同一个内存地址。
import copy
a = "i love python"
b = a
a1 = copy.copy(a)
a2 = copy.deepcopy(b)
print(id(a))
print(id(b))
print(id(a1))
print(id(a2))
#输出:
2114011486192
2114011486192
2114011486192
2114011486192

4.对于字典,列表等可变对象:
例1,关于赋值,只是创建一个变量,该变量仍指向原来内存地址;
#赋值
D = {'k1':'v1','k2':123,'k3':["str1",469]}
D2 = D
print(id(D))
print(id(D2))
#输出:
2178677065032
2178677065032

例2,浅拷贝,

#浅拷贝
D = {'k1':'v1','k2':123,'k3':["str1",469]}
D2 = copy.copy(D) #浅拷贝,额外创建第一层(变量名id改变,对象id不变,还是引用旧对象)
print(id(D))
print(id(D2))
print(id(D["k1"]))
print(id(D2["k1"]))
#输出;
1993456403784
1993456836488
1993456800856
1993456800856

例3:深拷贝,在内存中将所有的数据重新创建一份,值的存放位置不变。
D = {'k1':'v1','k2':123,'k3':["str1",469]}
D2 = copy.deepcopy(D)
print(id(D))
print(id(D2))
print(id(D["k3"]))
print(id(D2["k3"]))
print(id(D["k3"][0]))
print(id(D2["k3"][0]))
#输出:
2129861461320
2129861875016
2129863354440
2129863327624
2129861860856
2129861860856

 5.应用:
#浅拷贝,改变新字典,久字典也一起改变
dict = {"cpu":[100],"mem":[200],"disk":[300]}
new_dict = copy.copy(dict)
new_dict["cpu"][0] = 90
print(new_dict)
print(dict)
#输出:
{'cpu': [90], 'mem': [200], 'disk': [300]}
{'cpu': [90], 'mem': [200], 'disk': [300]}
#深拷贝,改变新字典,久字典没变
dict = {"cpu":[100],"mem":[200],"disk":[300]}
new_dict = copy.deepcopy(dict)
new_dict["cpu"][0] = 90
print(new_dict)
print(dict)
#输出:
{'cpu': [90], 'mem': [200], 'disk': [300]}
{'cpu': [100], 'mem': [200], 'disk': [300]}

参考:

http://www.cnblogs.com/repo/p/5425774.html

http://blog.csdn.net/jerry_1126/article/details/41852591

python学习笔记:深浅拷贝的使用和原理的更多相关文章

  1. Python学习(006)-深浅拷贝及集合

     深浅拷贝 import copy husband=['xiaoxin',123,[200000,100000]] wife=husband.copy() #浅拷贝 wife[0]='xiaohong ...

  2. python学习之深浅拷贝

    4.2 深浅拷贝 4.2.1 认识 首先应该知道python中变量在内存中是怎么存放的! 在python中,变量与变量的值占用不同的内存.变量占用的内存,并非直接存储数值,而存储的是值在内存中的地址. ...

  3. Python学习 :深浅拷贝

    深浅拷贝 一.浅拷贝 只拷贝第一层数据(不可变的数据类型),并创建新的内存空间进行储蓄,例如:字符串.整型.布尔 除了字符串以及整型,复杂的数据类型都使用一个共享的内存空间,例如:列表 列表使用的是同 ...

  4. Python学习-列表深浅拷贝

    一.先看一个简单的赋值语句 lst1 = ['France', 'Belgium', 'England'] lst2 = lst1 # lst1.append('Uruguay') lst2.appe ...

  5. python基础学习笔记——深浅拷贝

    2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 lst1 = ["⾦⽑狮王", "紫衫⻰王&qu ...

  6. day8 python学习 集合 深浅拷贝

    1.内存地址: 字符串在20位以内,没有空格,没有特殊字符的情况下,同样的字符串内存地址是一样的 2.元组中:在只有一个值的时在后边加逗号和没有逗号的区别 t1=(1) 不加逗号这个值是什么类型就打印 ...

  7. python学习笔记3---浅拷贝和深拷贝,file操作

    import copy a=[1,2,3,['a','b']] b=a c= copy.copy(a)---浅拷贝 d=copy.deepcopy(a)---深拷贝 file操作: python 文件 ...

  8. python学习day7 深浅拷贝&文件操作

    4-4 day07 深浅拷贝&文件操作 .get()用法 返回指定键的值,如果值不在字典中返回默认值. info={'k1':'v1,'K2':'v2'}mes = info.get('k1' ...

  9. python学习笔记:*args和**kwargs使用原理?

    一.*args和**kwargs原理 先看个例子: def test(*args,**kwargs): print("args =",args) print("kwarg ...

  10. Python学习笔记基础篇——总览

    Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...

随机推荐

  1. Java基础学习心得笔记

    对于很多只会C语言的初学者而言,面对java基础语法学习,反而感觉很难,其实其中最大的问题不是语法难,而是一种编程思想的转变.面向过程就是把你的代码封装成函数,然后依次去做一件事情,面向过程是把你要做 ...

  2. python unittest addCleanup中也加失败截图功能

    在python web自动化测试中失败截图方法汇总一文中提到了失败截图的方法 但在实际测试中,如果我们的测试用例中加了addCleanups动作,如果addCleanups中动作失败了,就不会截图.那 ...

  3. ruby 知识点随笔

    print .puts 和 p 方法的区别."" 与 ''  的区别. 处理控制台编码问题 >ruby -E utf-8 脚本文件名称 # 执行脚本 >irb -E u ...

  4. Java8 新特性之流式数据处理

    一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现.比如我们希望对一个包含整数的 ...

  5. CKFinker 2.5.0.1 去demo标示

    演示版会在文件浏览界面显示演示消息,分别是左下角(文件夹框下面)和列表框上部 都是通过修改ckfinder.js来实现 右下角标示: 查找: {if(C.getItem(E).rd("\x7 ...

  6. vivado/FPGA 使用小纪

    1.使用FPGA做为外部控制器的总线译码时,将总线时钟接在全局时钟脚上(MRCC),就算接在了局部时钟(SRCC)上,也要通过BUFG转为全局时钟走线,否则会因为local clk到各部分的时延较大引 ...

  7. [redis] 与redis cluster有关的学习笔记

    主要是以下三个官方文档,只略读了前两个,第三个还没有读. <redis cluster tutorial> <redis sentinel> <redis cluster ...

  8. Java如何获取图片验证码保存

    举例网站:https://my.1hai.cn/Login/?url=http://www.1hai.cn/ 一.场景:出于安全性考虑,越来越多的Web平台登录都会增加图形验证码(图片),或者短信验证 ...

  9. etcd集群的搭建

    由于最近在学习kubernetes,etcd作为kubernetes集群的主数据库,必须先启动. etcds实例名称 IP地址 Hostname etcd 1 192.168.142.161 kube ...

  10. Open_stack 有虚拟机端口不通的问题

    原因:流量表 解决办法:not修改流量表(容易出错,出错后果更严重):is迁移虚拟机这样会对应生成新的流量表,然后问题就解决了.