Python对象拷贝——深拷贝与浅拷贝
1. 对象赋值
对象的赋值实际上是对对象的引用。也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用。如:
>>> t1 = tuple('furzoom')
>>> t2 = t1
>>> id(t1),id(t2)
(139792198303936, 139792198303936)
上面t1和t2代表的是同一个对象。
2. 浅拷贝
除了上面将一个对象直接赋值给另一个对象外,还有两种常用的方法对对象进行拷贝:使用切片操作和工厂方法。
>>> car = ['grand', ['length', 4.85]]
>>> a4 = car[:]
>>> a6 = list(car)
>>> [hex(id(x)) for x in car, a4, a6]
['0x7f23e84da2d8', '0x7f23e84da128', '0x7f23e84da3f8']
通过创建汽车a4和a6,确实表示是不同的对象。现在继续完善a4和a6,修改它们的名字,和汽车长度。
>>> a4[0] = 'a4'
>>> a6[0] = 'a6'
>>> a4, a6
(['a4', ['length', 4.85]], ['a6', ['length', 4.85]])
>>> a4[1][1] = 4.761
>>> a4, a6
(['a4', ['length', 4.761]], ['a6', ['length', 4.761]])
修改汽车名字时,他们表现是正常的,而修改汽车车长时,发生了不期望的结果,修改a4的长度,同时也影响了a6的长度。
为什么会这样呢?原因在于只是针对序列做了浅拷贝。序列类型对象的浅拷贝是默认的拷贝,体现在:使用切片操作[:]、工厂函数、copy模块的copy函数。当改变a6汽车名字时,为什么没有体现在a4汽车上呢?这是因为名字是字符串类型,它是一个不可变类型,改变其内容将引用新建的对象。如下:
>>> a8 = list(car)
>>> [hex(id(x)) for x in car]
['0x7f23e84d7a80', '0x7f23e84da320']
>>> [hex(id(x)) for x in a8]
['0x7f23e84d7a80', '0x7f23e84da320']
>>> [hex(id(x)) for x in a4]
['0x7f23e84d4d78', '0x7f23e84da320']
>>> [hex(id(x)) for x in a6]
['0x7f23e84d4e40', '0x7f23e84da320']
在a4和a6的第二项,它们引用的是同一个对象。
3. 深拷贝
要想避免上面的这种影响,需要对列表进行深拷贝。需要使用copy模块的deepcopy()函数。
如:
>>> car = ['grand', ['length', 4.85]]
>>> a4 = car
>>> import copy
>>> a6 = copy.deepcopy(car)
>>> [hex(id(x)) for x in car, a4, a6]
['0x7f23e84da098', '0x7f23e84da098', '0x7f23e84da440']
>>> a4[0] = 'a4'
>>> a6[0] = 'a6'
>>> a4,a6
(['a4', ['length', 4.85]], ['a6', ['length', 4.85]])
>>> a4[1][1] = 4.761
>>> a4,a6
(['a4', ['length', 4.761]], ['a6', ['length', 4.85]])
另,在copy模块中,只有两个函数,copy
和deepcopy
。
Python对象拷贝——深拷贝与浅拷贝的更多相关文章
- Python 对象的深拷贝与浅拷贝 -- (转)
本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标 ...
- **Python中的深拷贝和浅拷贝详解
Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要 ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- java 复制Map对象(深拷贝与浅拷贝)
java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...
- 谈谈java中对象的深拷贝与浅拷贝
知识点:java中关于Object.clone方法,对象的深拷贝与浅拷贝 引言: 在一些场景中,我们需要获取到一个对象的拷贝,这时候就可以用java中的Object.clone方法进行对象的复制,得到 ...
- python中的深拷贝与浅拷贝
深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...
- 浅谈python 复制(深拷贝,浅拷贝)
博客参考:点击这里 python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示 1.赋值: a=[1 ...
- python中的深拷贝和浅拷贝理解
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用.以下分两个思路来分别理解浅拷贝和深拷贝: 利用切 ...
- python中的深拷贝和浅拷贝
python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...
随机推荐
- (1)angularJs
一. 1.下载 https://angularjs.org/ 2.网络引用 https://code.angularjs.org/ 3.模块内引用 angularjs <body ng-app& ...
- Java 对象的序列化、反序列化
对象的序列化(Serialize):将内存中的Java对象转换为与平台无关的二进制流(字节序列),然后存储在磁盘文件中,或通过网络传输给另一个网络节点. 对象的反序列化(Deserialize):获取 ...
- Codeforces Round #295 (Div. 1) C. Pluses everywhere
昨天ZZD大神邀请我做一道题,说这题很有趣啊. 哇,然后我被虐了. Orz ZZD 题目大意: 你有一个长度为n的'0-9'串,你要在其中加入k个'+'号,每种方案就会形成一个算式,算式算出来的值记做 ...
- SpringBoot中@EnableAutoConfiguration注解用法收集
参考: http://blog.csdn.net/xiaoyu411502/article/details/52770723 https://docs.spring.io/spring-boot/do ...
- Java中HashMap的初始容量设置
根据阿里巴巴Java开发手册上建议HashMap初始化时设置已知的大小,如果不超过16个,那么设置成默认大小16: 集合初始化时, 指定集合初始值大小. 说明: HashMap使用HashMap(in ...
- 一个能让你了解所有函数调用顺序的Android库
http://mobile.51cto.com/android-536059.htm 原理 本库其实并没有什么黑科技,本库也没有java代码,核心就是2个build.gradle中的task.首先,原 ...
- 学习笔记 Java类的封装、继承和多态 2014.7.10
1.问题:toString()没搞懂? int a = 1; Integer aa = new Integer(a); //这是实现的过程 System.out.println("Hello ...
- Cocos2d-x移植安卓的笔记
一.下载所需软件 Java SDK http://www.oracle.com/technetwork/java/javase/downloads/index.html Windows x64 ...
- 转:scanf的用法
https://blog.csdn.net/u012421456/article/details/18501309 scanf()[通过键盘将数据输入到变量中] 它有两种用法: 用法一: scanf( ...
- Class doesn't implement Cloneable之怪象
1. 报错: -20 ::): threadid=: thread exiting with uncaught exception (group=0x4001d400) -20 ::): FATAL ...