python中的深拷贝和浅拷贝理解 分类: python基础学习 2014-03-10 15:50 292人阅读 评论(0) 收藏
2014-03-10 15:50
811 查看
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。以下分两个思路来分别理解浅拷贝和深拷贝:
利用切片操作和工厂方法list方法拷贝
利用copy中的deepcopy方法进行拷贝
1、利用切片操作和工厂方法list方法拷贝
代码场景:有一个小伙jack,tom通过切片操作拷贝jack,anny通过工厂方法拷贝jack。
来看下三者的id值:
从id值来看,三者是不同的对象。为tom和anny重新命名为各自的名称:
从这里来看一切正常,可是anny只有18岁,重新为anny定义岁数。
这时候奇怪的事情发生了,jack、tom、anny的岁数都发生了改变,都变成了18了。jack、tom、anny他们应当都是不同的对象,怎么会互相影响呢?看下jack,tom,anny的内部元素每个元素id:
恍然大悟,原来jack、tom、anny的岁数元素指向的是同一个元素。修改了其中一个,当然影响其他人了。那为什么修改名称没影响呢?原来在python中字符串不可以修改,所以在为tom和anny重新命名的时候,会重新创建一个’tom’和’anny’对象,替换旧的’jack’对象。为了便于理解,我画了一个草图:
2、利用copy中的deepcopy方法进行拷贝
为了让他们之间不互相影响,用deepcopy来试试
根据第一个思路进行重命名,重定岁数操作:
这时候他们之间就不会互相影响了。打印出每个人的内部元素每个id:
他们的内部元素也都指向了不同的对象。
小结:
思路一:利用切片操作和工厂方法list方法拷贝就叫浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。
思路二:利用copy中的deepcopy方法进行拷贝就叫做深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。
但是对于数字,字符串和其他原子类型对象等,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
利用切片操作和工厂方法list方法拷贝
利用copy中的deepcopy方法进行拷贝
1、利用切片操作和工厂方法list方法拷贝
代码场景:有一个小伙jack,tom通过切片操作拷贝jack,anny通过工厂方法拷贝jack。
>>> jack = ['jack', ['age', 20]] >>> tom = jack[:] >>> anny = list(jack)
来看下三者的id值:
>>> print id(jack), id(tom), id(anny) 144846988 144977164 144977388
从id值来看,三者是不同的对象。为tom和anny重新命名为各自的名称:
>>> tom[0] = 'tom' >>> anny[0] = 'anny' >>> print jack, tom, anny ['jack', ['age', 20]] ['tom', ['age', 20]] ['anny', ['age', 20]]
从这里来看一切正常,可是anny只有18岁,重新为anny定义岁数。
>>> anny[1][1] = 18 >>> print jack, tom, anny ['jack', ['age', 18]] ['tom', ['age', 18]] ['anny', ['age', 18]]
这时候奇怪的事情发生了,jack、tom、anny的岁数都发生了改变,都变成了18了。jack、tom、anny他们应当都是不同的对象,怎么会互相影响呢?看下jack,tom,anny的内部元素每个元素id:
>>> [id(x) for x in jack] [3073896320L, 3073777580L] >>> [id(x) for x in tom] [144870744, 3073777580L] >>> [id(x) for x in anny] [144977344, 3073777580L]
恍然大悟,原来jack、tom、anny的岁数元素指向的是同一个元素。修改了其中一个,当然影响其他人了。那为什么修改名称没影响呢?原来在python中字符串不可以修改,所以在为tom和anny重新命名的时候,会重新创建一个’tom’和’anny’对象,替换旧的’jack’对象。为了便于理解,我画了一个草图:
2、利用copy中的deepcopy方法进行拷贝
为了让他们之间不互相影响,用deepcopy来试试
>>> jack = ['jack', ['age', '20']] >>> import copy >>> tom = copy.deepcopy(jack) >>> anny = copy.deepcopy(jack)
根据第一个思路进行重命名,重定岁数操作:
>>> tom[0] = 'tom' >>> anny[0] = 'anny' >>> print jack, tom, anny ['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', '20']] >>> anny[1][1] = 18 >>> print jack, tom, anny ['jack', ['age', '20']] ['tom', ['age', '20']] ['anny', ['age', 18]]
这时候他们之间就不会互相影响了。打印出每个人的内部元素每个id:
>>> [id(x) for x in jack] [139132064, 3073507244L] >>> [id(x) for x in tom] [139137464, 139132204] >>> [id(x) for x in anny] [139141632, 139157548]
他们的内部元素也都指向了不同的对象。
小结:
思路一:利用切片操作和工厂方法list方法拷贝就叫浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。
思路二:利用copy中的deepcopy方法进行拷贝就叫做深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。
但是对于数字,字符串和其他原子类型对象等,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
相关文章推荐
- 使用getattr() 分类: python基础学习 divide into python 2014-02-24 15:50 198人阅读 评论(0) 收藏
- 猜数字 分类: python 小练习 python基础学习 2013-06-20 15:16 160人阅读 评论(0) 收藏
- Python 设置系统默认编码 分类: python基础学习 2013-12-11 10:04 212人阅读 评论(0) 收藏
- python之string模块 分类: python基础学习 python Module 2013-08-27 13:58 241人阅读 评论(0) 收藏
- python 操作windows下的目录 分类: python python基础学习 2013-07-30 17:30 274人阅读 评论(0) 收藏
- python数据持久存储:pickle模块的基本使用 分类: python python基础学习 python 小练习 2013-06-17 14:41 209人阅读 评论(0) 收藏
- 变量及地址 分类: python基础学习 2013-06-15 15:32 190人阅读 评论(0) 收藏
- n&1判断奇偶 分类: python基础学习 测试 2014-02-10 15:41 636人阅读 评论(0) 收藏
- Linux下python升级至2.7步骤 分类: python基础学习 python下载 2013-09-29 11:24 4266人阅读 评论(2) 收藏
- 函数名function是一个数据类型,可以赋值 分类: python基础学习 2013-09-12 11:01 366人阅读 评论(0) 收藏
- 使用os.popen/commands.getoutput查询指定端口号的服务 分类: python 小练习 open()文件读写 python基础学习 2013-09-17 17:49 798人阅读 评论(0) 收藏
- python random模块 分类: python python Module python基础学习 2013-06-26 12:06 383人阅读 评论(0) 收藏
- Python 使用 Xlrd/xlwt 操作 Excel 分类: python基础学习 2014-03-17 12:06 958人阅读 评论(0) 收藏
- yield生成器对象返回Fiabs元素 分类: python 小练习 python基础学习 2014-01-13 10:28 193人阅读 评论(0) 收藏
- file()创建文件方法 分类: python python基础学习 2012-12-24 18:17 239人阅读 评论(0) 收藏
- global全局变量 分类: python基础学习 2013-06-30 09:54 181人阅读 评论(0) 收藏
- 使用set()求出列表交集 分类: python基础学习 2013-06-16 17:00 241人阅读 评论(0) 收藏
- 文件操作注意事项 分类: python 小练习 python基础学习 open()文件读写 2013-12-03 11:05 532人阅读 评论(0) 收藏
- Python下划线与命名规范 分类: python基础学习 2013-09-02 21:29 419人阅读 评论(0) 收藏
- python参数 分类: python基础学习 python 2013-08-23 15:06 217人阅读 评论(0) 收藏