编者注:本文主要参考了《Python核心编程(第二版)》  

以下都是参考资料后,我自己的理解,如有错误希望大家不吝赐教。

大家有没有遇到这样一种情况,对象赋值后,对其中一个变量进行修改,另外一个变量的值也改变了。比如:

person = ['name', ['saving', 100]]
hubby = person
wifey = person
hubby[0] = 'joe'
wifey[0] = 'jane'
print hubby, wifey
hubby[1][1] = 50
print hubby, wifey
>>>['jane', ['saving', 100]] ['jane', ['saving', 100]]
['jane', ['saving', 50]] ['jane', ['saving', 50]]

以上的对象赋值实际上是简单的对象引用。也就是说当你创建一个对象,然后把他赋给另一个变量的时候,python并没有拷贝这个对象,而是拷贝了这个对象的引用。可以看出,hubby,wifey只是拷贝了person的引用,且是对person变量名,即列表整体的引用。

person = ['name', ['saving', 100]]
hubby = person
wifey = person
print [id(x) for x in person,hubby,wifey]
print [id(x) for x in person]
print [id(x) for x in hubby]
print [id(x) for x in wifey]
>>>[58507784L, 46008008L, 46008968L]
[37770104L, 58507336L]
[37770104L, 58507336L]
[37770104L, 58507336L]

可以看出,三个变量地址不一样,但三个变量的内容的地址一样,所以赋值后显示的结果一样。

常使用的浅拷贝类型有:
(1)完全切片操作[:]
(2)利用工厂函数list(),dict()等
(3)使用copy模块的copy函数

person = ['name', ['saving', 100]]
hubby = list(person)
wifey = person[:]
print [id(x) for x in person,hubby,wifey]
print [id(x) for x in person]
print [id(x) for x in hubby]
print [id(x) for x in wifey]
hubby[0] = 'joe'
wifey[0] = 'jane'
print hubby, wifey
hubby[1][1] = 50
print hubby, wifey
>>>[56541704L, 45680328L, 56541640L]
[37573496L, 56541256L]
[37573496L, 56541256L]
[37573496L, 56541256L]
['joe', ['saving', 100]] ['jane', ['saving', 100]]
['joe', ['saving', 50]] ['jane', ['saving', 50]]

   为什么这种浅拷贝hubby,wifey的名字不一样呢?第二个列表中值一样呢?因为list()和完全切边操作[:]是将person里的每个内容赋值,是对序列的引用。且这两个列表中第一个对象(字符串类型)是不可变的,第二个对象(一个列表)是可变的。正因如此,当进行浅拷贝时,字符串被显示的拷贝,并创建了一个字符串对象。而列表元素只是把它的引用复制了一下,并不是它的成员。

注意:
第一,非容器类型(比如数字,字符串,和其他‘原子’类型的对象,像xrange等)没有拷贝一说,浅拷贝是用完全切片操作完成的。第二,如果元组变量只包含原子类型对象,它的深拷贝将不会进行,只能得到一个浅拷贝。

import copy
person = ['name', ('saving', 100)]
hubby = person
wifey = copy.deepcopy(person)
print [id(x) for x in person,hubby,wifey]
print [id(x) for x in person]
print [id(x) for x in hubby]
print [id(x) for x in wifey]
>>>[56902216L, 56902216L, 56902152L]
[42095480L, 44124104L]
[42095480L, 44124104L]
[42095480L, 44124104L]

  

Python中的浅拷贝与深拷贝的更多相关文章

  1. python中的浅拷贝,深拷贝

    直接引用,间接引用 # 1.列表存储的是索引对应值的内存地址,值会单独的开辟一个内存空间 list = ["a","b"] 内存里面存储的就是list[0],l ...

  2. python中的浅拷贝和深拷贝

    1.赋值语句 a = 'abc' b = a print id(a) print id(b) # id(a):29283464 # id(b):29283464 通过简单的复制,我们可以看到,a b其 ...

  3. 16.python中的浅拷贝和深拷贝

    在讲什么是深浅拷贝之前,我们先来看这样一个现象: a = ['scolia', 123, [], ] b = a[:] b[2].append(666) print a print b

  4. (转+原)python中的浅拷贝和深拷贝

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6069722.html 原网址: http://blog.csdn.net/sunshine_in_mo ...

  5. Python 中的浅拷贝和深拷贝

    1. 列表和字典,直接赋值,都是浅拷贝,即赋值双方指向同一地址,因为 Python 对可变对象按引用传递. >>> a = [1, 2, 3] >>> b = a ...

  6. Python中的赋值、深拷贝与浅拷贝(内存地址)

    Python中的赋值.深拷贝与浅拷贝(内存地址) 1.python中的可变对象与不可变对象 (1) 可变对象:dict,list def dict_test(): a = {} b = a print ...

  7. 【转】JAVA中的浅拷贝和深拷贝

    原文网址:http://blog.bd17kaka.net/blog/2013/06/25/java-deep-copy/ JAVA中的浅拷贝和深拷贝(shallow copy and deep co ...

  8. python中的浅拷贝与赋值不同

    Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...

  9. Python 引用、浅拷贝、深拷贝解析

    引用 Python是动态数据类型的语言,故在对变量进行赋值时是不用制定变量类型的. 或者说,你可以把变量赋值的过程,当作是贴一个标签,去引用该数据. 看下面的例子: In [54]: a=4 In [ ...

随机推荐

  1. [国嵌攻略][163][linux-usb软件系统架构]

    软件系统架构 1.主机端软件架构 USB设备驱动->USB核心->USB主控制器驱动->USB主控制器 2.设备端软件架构 Gadget驱动->Gadget API->U ...

  2. oracle和mysql分页

    mysql分页 关键字limit,limit m,n 其中m表示起始位置的下标,下标从0开始.n表示要显示的条数,比如要查询一个表的第2到5条数据. ,; oracle分页 关键字rownum, ro ...

  3. 番外篇--Moddule Zero启动模板

    1.3 ABPZero - 启动模板 1.3.1 简介 使用ABP和moudle-zero开始一个新项目的最简单的方式是在模板页创建模板.记住要勾选 Include module zero. 在创建并 ...

  4. Java多线程编程—锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  5. 正则API

    正则表达式:规定字符串中字符出现规律的公式 如果备选字符列表中个别字符之间是连续的,可用-省略中间的字符.比如: 匹配1位数字:   [0-9]匹配1位小写字母 : [a-z] 匹配1位大写字母 : ...

  6. cuda纹理内存的使用

    CUDA纹理内存的访问速度比全局内存要快,因此处理图像数据时,使用纹理内存是一个提升性能的好方法. 贴一段自己写的简单的实现两幅图像加权和的代码,使用纹理内存实现. 输入:两幅图 lena, moon ...

  7. Swift2

    Swift 里的数组和字典虽然都是结构体(struct),但在参数传递过程中处理方式却不一样,默认 Array 是引用传递,Dictionary 是值传递.而在 Java 中,由于数组和 Map 都是 ...

  8. Excel的列编号 例如:A对应1,Z对应26,AA对应27,AZ对应52的JavaScript怎么写?

    今天碰到的题目,当时不会.回来想了一会,调试了一下,然后想上网对答案,发现竟然没有!!! function str(num){ if(num<=0){ alert("excel表格貌似 ...

  9. Ring3句柄表的枚举

    由于windows并没有给出枚举所有句柄所用到的API,要获得句柄,我们必须使用未公开的Native API才可以,使用如下函数: NTSTATUS WINAPI NtQuerySystemInfor ...

  10. C语言知识点总结

    本文采用思维导图的方式撰写,更好的表述了各知识点之间的关系,方便大家理解和记忆.这个总结尚未包含C语言数据结构与算法部分,后续会陆续更新出来,文中有漏掉的知识点,还请大家多多指正.