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 相关文章推荐
windows 下python+numpy安装实用教程
Dec 23 Python
python中实现数组和列表读取一列的方法
Apr 03 Python
Python 网络爬虫--关于简单的模拟登录实例讲解
Jun 01 Python
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
Jun 13 Python
解决python 自动安装缺少模块的问题
Oct 22 Python
Python3.6中Twisted模块安装的问题与解决
Apr 15 Python
详解Python静态网页爬取获取高清壁纸
Apr 23 Python
windows 10 设定计划任务自动执行 python 脚本的方法
Sep 11 Python
用python画一只可爱的皮卡丘实例
Nov 21 Python
python 导入数据及作图的实现
Dec 03 Python
如何用 Python 处理不平衡数据集
Jan 04 Python
Python数据分析之pandas读取数据
Jun 02 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新建文件自动编号的思路与实现
2011/06/27 PHP
浏览器关闭后,能继续执行的php函数(ignore_user_abort)
2012/08/01 PHP
php 模拟POST提交的2种方法详解
2013/06/17 PHP
php设置允许大文件上传示例代码
2014/03/10 PHP
PHP把网页保存为word文件的三种方法
2014/04/01 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
日常整理PHP中简单的图形处理(经典)
2015/10/26 PHP
phplist及phpmailer(组合使用)通过gmail发送邮件的配置方法
2016/03/30 PHP
thinkphp表单上传文件并将文件路径保存到数据库中
2016/07/28 PHP
Gambit vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
原生javascript获取元素样式属性值的方法
2010/12/25 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
json数据的列循环示例
2013/09/06 Javascript
js实现鼠标划过给div加透明度的方法
2015/05/25 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
layer.open的自适应及居中及子页面标题的修改方法
2019/09/05 Javascript
JavaScript This指向问题详解
2019/11/25 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
在Python中调用ggplot的三种方法
2015/04/08 Python
python实现的简单RPG游戏流程实例
2015/06/28 Python
Django框架下在视图中使用模版的方法
2015/07/16 Python
windows中安装Python3.8.0的实现方法
2019/11/19 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
加拿大建筑和装修专家:Reno-Depot
2017/12/21 全球购物
SHEIN香港:价格实惠的女性时尚服装
2018/08/14 全球购物
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
linux比较文件内容的命令是什么
2015/09/23 面试题
企业门卫岗位职责
2013/12/12 职场文书
初三化学教学反思
2014/01/23 职场文书
80后职场人的职业生涯规划
2014/03/08 职场文书
小学生民族团结演讲稿
2014/08/27 职场文书
大学社团招新的通讯稿
2014/09/10 职场文书
学会Python数据可视化必须尝试这7个库
2021/06/16 Python