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程序设计入门(1)基本语法简介
Jun 13 Python
用Python生成器实现微线程编程的教程
Apr 13 Python
对python3 urllib包与http包的使用详解
May 10 Python
Django中间件实现拦截器的方法
Jun 01 Python
python 地图经纬度转换、纠偏的实例代码
Aug 06 Python
Python计算一个点到所有点的欧式距离实现方法
Jul 04 Python
Django Channels 实现点对点实时聊天和消息推送功能
Jul 17 Python
python多进程重复加载的解决方式
Dec 13 Python
Python定义函数时参数有默认值问题解决
Dec 19 Python
matlab中imadjust函数的作用及应用举例
Feb 27 Python
Python 防止死锁的方法
Jul 29 Python
在pycharm创建scrapy项目的实现步骤
Dec 01 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
PHP无限分类(树形类)
2013/09/28 PHP
Laravel5框架自定义错误页面配置操作示例
2019/04/17 PHP
js调试工具 Javascript Debug Toolkit 2.0.0版本发布
2008/12/02 Javascript
JS实现下拉框的动态添加(附效果)
2013/04/03 Javascript
JavaScript中用于生成随机数的Math.random()方法
2015/06/15 Javascript
理解和运用JavaScript的闭包机制
2015/08/13 Javascript
jQuery实现简单下拉导航效果
2015/09/07 Javascript
在微信、支付宝、百度钱包实现点击返回按钮关闭当前页面和窗口的方法
2016/08/05 Javascript
jQuery下拉菜单的实现代码
2016/11/03 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
Vue中封装input组件的实例详解
2017/10/17 Javascript
Bootstrap Table 搜索框和查询功能
2017/11/30 Javascript
在knockoutjs 上自己实现的flux(实例讲解)
2017/12/18 Javascript
vue2.0路由切换后页面滚动位置不变BUG的解决方法
2018/03/14 Javascript
Angular 组件之间的交互的示例代码
2018/03/24 Javascript
vue+axios 前端实现的常用拦截的代码示例
2018/08/23 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
Vue 数组和对象更新,但是页面没有刷新的解决方式
2019/11/09 Javascript
JS数组方法push()、pop()用法实例分析
2020/01/18 Javascript
vue实现购物车加减
2020/05/30 Javascript
Nuxt配置Element-UI按需引入的操作方法
2020/07/06 Javascript
Python实现基于权重的随机数2种方法
2015/04/28 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
python 通过 socket 发送文件的实例代码
2018/08/14 Python
删除DataFrame中值全为NaN或者包含有NaN的列或行方法
2018/11/06 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
Python TKinter如何自动关闭主窗口
2020/02/26 Python
python基于socket函数实现端口扫描
2020/05/28 Python
解决pytorch下出现multi-target not supported at的一种可能原因
2021/02/06 Python
如何用 Python 制作 GitHub 消息助手
2021/02/20 Python
德国受欢迎的旅游和休闲网站:lastminute.de
2019/09/23 全球购物
大学生翘课检讨书范文
2014/10/06 职场文书
西安兵马俑导游词
2015/02/02 职场文书
消防演习通知
2015/04/25 职场文书
家长会主持词开场白
2015/05/29 职场文书
python利用pandas分析学生期末成绩实例代码
2021/07/09 Python