python深浅拷贝探究
2016-07-04 14:00
239 查看
python中深浅拷贝是经常出现的,大多数情况下,我们无意识的简单赋值都是浅拷贝的.
那么什么是深拷贝,什么是浅拷贝呢?简单来说,浅拷贝就是创建一个指向被拷贝对象引用(指针)的对象或者变量,显然这是一种指针间的拷贝;深拷贝就不一样了,它是对象内部资源值的拷贝,会在内存中重新开辟一段空间用来存放被拷贝对象的资源.下面通过例子来说明:
id(obejct)用于获取变量的内存地址,可见上面的简单赋值告诉我们,对a的赋值语句是基于浅拷贝实现的,不同的值赋给a会使得a指向不同的内存地址.
下面再举一个字典的例子:
那么如何实现深拷贝呢?起始很简单,使用copy模块的deepcopy函数.
总结一下,在python中大多数情况下,如果不使用deepcopy的话,都是浅拷贝的,那么对于浅拷贝需要注意:
如果是简单类型变量(整型,浮点型,字符串等)的浅拷贝,修改’辅本’并不会影响原始的值.你可以把python的所有变量名看成是一个指针变量,既然是指针变量,你修改了它,也仅仅只是将它指到别的地方,并不会影响原本空间的值.
列表,字典等复杂类型变量的浅拷贝,修改列表或者字典的元素,都会改变原始的值,这里的修改包括增加,删除,更新值,不包括这个列表,字典的置空,或者别的整体上的修改,原因很简单修改列表,字典的内部元素,都是在同一个空间做的,所以会影响所有指向该空间的’副本’,但是后者就不同,那就相当于直接到另一个内存空间了.
那么什么是深拷贝,什么是浅拷贝呢?简单来说,浅拷贝就是创建一个指向被拷贝对象引用(指针)的对象或者变量,显然这是一种指针间的拷贝;深拷贝就不一样了,它是对象内部资源值的拷贝,会在内存中重新开辟一段空间用来存放被拷贝对象的资源.下面通过例子来说明:
>>>a=1 >>>id(a) >>>21229912 >>>a=2 >>>id(a) >>>21229888
id(obejct)用于获取变量的内存地址,可见上面的简单赋值告诉我们,对a的赋值语句是基于浅拷贝实现的,不同的值赋给a会使得a指向不同的内存地址.
>>>a=[1,2,3] >>>b=[i for i in a] >>>print 'a:%s;b:%s' % (id(a),id(b)) >>>a:140075989324072;b:140075989459024 #a和b的地址不一样,是不是说明就是深拷贝了呢?看看下面 >>>print '%s-%s-%s' % (id(a[0]),id(a[1]),id(a[2])) >>>21229912-21229888-21229864 >>>print '%s-%s-%s' % (id(b[0]),id(b[1]),id(b[2])) >>>21229912-21229888-21229864 #可见虽然a和b位于不同的内存空间,但a,b中每个元素都是指向相同空间的,所以还是浅拷贝 >>>a[1]=5 >>>a >>>[1,5,3] >>>b >>>[1,2,3] #为什么b没用变化,应该很好理解吧,简单来说,就是a[1]的指向其他地方了,当然不会影响b >>>c=a #由于是浅拷贝,故而c和a指向相同的内存地址,所以a的改变一定会影响c >>>c >>>[1,5,3] >>>a[1]=2 >>>a >>>[1,2,3] >>>c >>>[1,2,3]
下面再举一个字典的例子:
>>>a={'name':['John','Mike'],'age':23} >>>b=a #同上,a和b一样,都是指向相同的空间,相当于C++的引用.但是也有区别,比如说: >>>b={} >>>a >>>{'name':['John','Mike'],'age':23} >>>c=a.copy() #依旧是浅拷贝 >>>c['age']=24 >>>a >>>{'name':['John','Mike'],'age':23} #应该知道原因吧,同上. >>>c['name'].append('Joker') >>>a >>>{'name':['John','Mike','Joker'],'age':23} #因为是浅拷贝,故而对列表的修改自然会影响原始的.
那么如何实现深拷贝呢?起始很简单,使用copy模块的deepcopy函数.
>>>a={'name':['John','Mike'],'age':23} >>>b=deepcopy(a) #深拷贝 >>>b['name'].append('Joker') >>>a >>>{'name':['John','Mike'],'age':23}
总结一下,在python中大多数情况下,如果不使用deepcopy的话,都是浅拷贝的,那么对于浅拷贝需要注意:
如果是简单类型变量(整型,浮点型,字符串等)的浅拷贝,修改’辅本’并不会影响原始的值.你可以把python的所有变量名看成是一个指针变量,既然是指针变量,你修改了它,也仅仅只是将它指到别的地方,并不会影响原本空间的值.
列表,字典等复杂类型变量的浅拷贝,修改列表或者字典的元素,都会改变原始的值,这里的修改包括增加,删除,更新值,不包括这个列表,字典的置空,或者别的整体上的修改,原因很简单修改列表,字典的内部元素,都是在同一个空间做的,所以会影响所有指向该空间的’副本’,但是后者就不同,那就相当于直接到另一个内存空间了.
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例