Python中对象的引用与复制代码示例


Posted in Python onDecember 04, 2017

可以说Python没有赋值,只有引用。你这样相当于创建了一个引用自身的结构,所以导致了无限循环。为了理解这个问题,有个基本概念需要搞清楚。

Python没有「变量」,我们平时所说的变量其实只是「标签」,是引用。

python中,"a=b"表示的是对象a引用对象b,对象a本身没有单独分配内存空间(重要:不是复制!),它指向计算机中存储对象b的内存。因此,要想将一个对象复制为另一个对象,不能简单地用等号操作,要使用其它的方法。如序列类的对象是(列表、元组)要使用切片操作符(即':')来做复制。

在python进行像b = a这样的赋值时,只会创建一个对a的新引用,使a的引用计数加1,而不会创建新的对象:

>>> a = 'xyz'
>>> import sys
>>> sys.getrefcount(a)
3
>>> b = a
>>> sys.getrefcount(b)
4
>>> id(a)
88292288L
>>> id(b)
88292288L

这样,当引用的对象是可变对象的时候(列表,字典,可变集合等),会产生意料之外的行为:

>>> a = [1, 2, 3, 4]
>>> b = a
>>> b.append(5)
>>> a
[1, 2, 3, 4, 5]

因为a和b引用的是同一对象,改变其中一个,另外一个也会随之改变。当我们想建立一个副本而不是引用时,可以复制对象。

复制对象一般使用copy模块:

>>> a = [1, 2, 3, 4]
>>> import copy
>>> b = copy.copy(a)
>>> b.append(5)
>>> b
[1, 2, 3, 4, 5]
>>> a
[1, 2, 3, 4]

这样就可以了,但这种复制是一种浅复制,复制的新对象中包含的是对原始对象中的项的引用,如果对象的项为可变对象,也会产生不可控行为:

>>> a = [1, [1, 2]]
>>> b = copy.copy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2, 3]]

这时候就要使用深复制了。深复制将创建一个新对象,并递归地复制它所包含的所有对象:

>>> a = [1, [1, 2]]
>>> b = copy.deepcopy(a)
>>> b[1].append(3)
>>> b
[1, [1, 2, 3]]
>>> a
[1, [1, 2]]

对于不可改变的对象而言(字符串,数字,元组)等,没有必要拷贝,因为它们是不可改变的,不用担心会不经意间改动了它们。拷贝操作也只会得到原对象:

>>> a = (1, 2, 3)
>>> b = copy.copy(a)
>>> a is b
True

对于可变对象来(列表,字典,可变集合)来说,可以分别使用内置函数list(),dict(),set()来进行浅复制,速度是比使用copy模块快的。

列表也可以使用切片进行浅复制:

>>> a = [1, 2, 3, 4]
>>> b = a[:]
>>> a is b
False
>>> b
[1, 2, 3, 4]

对序列数据类型(字符串,列表,元组)进行*操作时,也仅仅是复制了对象中项的引用,如果使用*创建一个多维列表:

>>> a = [1, 2, 3]
>>> b = [a]
>>> c = b * 3
>>> a.append(4)
>>> c
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]

最好是在列表推导中使用浅复制来创建多维列表,可以避免隐式的引用共享:

>>> a = [1, 2, 3]
>>> c = [list(a) for i in range(3)]
>>> a.append(4)
>>> c
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]

总结

以上就是本文关于Python中对象的引用与复制代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。

Python 相关文章推荐
python中使用urllib2获取http请求状态码的代码例子
Jul 07 Python
python实现将内容分行输出
Nov 05 Python
python字符串的常用操作方法小结
May 21 Python
python实现简单爬虫功能的示例
Oct 24 Python
Python实现感知器模型、两层神经网络
Dec 19 Python
详解python中的Turtle函数库
Nov 19 Python
Golang GBK转UTF-8的例子
Aug 26 Python
jupyter lab的目录调整及设置默认浏览器为chrome的方法
Apr 10 Python
python如何求圆的面积
Jul 01 Python
Keras实现DenseNet结构操作
Jul 06 Python
matplotlib绘制多子图共享鼠标光标的方法示例
Jan 08 Python
Python 读取千万级数据自动写入 MySQL 数据库
Jun 28 Python
Python3 Random模块代码详解
Dec 04 #Python
利用python爬取斗鱼app中照片方法实例
Dec 03 #Python
CentOS 6.5中安装Python 3.6.2的方法步骤
Dec 03 #Python
python3利用smtplib通过qq邮箱发送邮件方法示例
Dec 03 #Python
Python中类的初始化特殊方法
Dec 01 #Python
Python抓取框架Scrapy爬虫入门:页面提取
Dec 01 #Python
Python实现调度算法代码详解
Dec 01 #Python
You might like
一个简易需要注册的留言版程序
2006/10/09 PHP
phpmyadmin中配置文件现在需要绝密的短语密码的解决方法
2007/02/11 PHP
PHP实现随机数字、字母的验证码功能
2018/08/01 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
js关于命名空间的函数实例
2015/02/05 Javascript
浅析BootStrap模态框的使用(经典)
2016/04/29 Javascript
用JavaScript动态建立或增加CSS样式表的实现方法
2016/05/20 Javascript
js中window.open的参数及注意注意事项
2016/07/06 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
2017/03/03 Javascript
解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
2017/05/05 Javascript
Angular.Js中ng-include指令的使用与实现
2017/05/07 Javascript
10 种最常见的 Javascript 错误(频率最高)
2018/02/08 Javascript
在 Angular中 使用 Lodash 的方法
2018/02/11 Javascript
JS 实现缓存算法的示例(FIFO/LRU)
2018/03/20 Javascript
JavaScript如何实现元素全排列实例代码
2019/05/14 Javascript
jquery实现图片无缝滚动 蒙版遮蔽效果
2020/01/11 jQuery
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
Python实现Kmeans聚类算法
2020/06/10 Python
Django实现网页分页功能
2019/10/31 Python
python 如何调用 dubbo 接口
2020/09/24 Python
Django生成数据库及添加用户报错解决方案
2020/10/09 Python
python爬取豆瓣电影排行榜(requests)的示例代码
2021/02/18 Python
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
Expedia西班牙:预订酒店、机票、旅行和廉价度假套餐
2019/04/10 全球购物
英国办公家具网站:Furniture At Work
2019/10/07 全球购物
个人简历中的自我评价怎么写
2014/01/26 职场文书
协议书范本
2014/04/23 职场文书
单位在职证明书
2014/09/11 职场文书
完整版商业计划书
2014/09/15 职场文书
死亡赔偿协议书
2015/01/28 职场文书
颐和园的导游词
2015/01/30 职场文书
Django如何与Ajax交互
2021/04/29 Python
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL
NodeJs使用webpack打包项目的方法详解
2022/02/28 NodeJs
apache虚拟主机配置的三种方式(小结)
2022/07/23 Servers