Python中的引用和拷贝浅析


Posted in Python onNovember 22, 2014

If an object's value can be modified, the object is said to be mutable. If the value cannot be modified,the object is said to be immutable.

mutable 可变类型,例如 list,set,自定义类型(等价于C#中的引用类型);

immutable 不可变类型,例如string,numbers等(等价于C#中的值类型);

一、引用和拷贝(references and copies)

当程序中使用=赋值操作符时,例如a=b,

对于不可变的对象,a作为b的一个拷贝被创建,a和b将指向不同的内存地址,a和b相互独立。

def TestCopy():

    a = 10

    b = a

    a =20

    print (b) #b still is 10

但是对于可变的对象,a作为b的一个引用被创建,a和b的元素公用相同的内存地址,a和b的元素共享。
def TestRef():

    a=[1,2,3,4]

    b=a   #b is a reference to a

    print (b is a) # True

    b[2] = -100 #change an element in b

    print (a) # a also changed to [1,2,-100,4]

二、深拷贝和浅拷贝(shallow copy and deep copy)

为了避免可变对象指向同一个对象,必须创建一个新的拷贝,而不是引用。
在python中可以对容器对象(例如lists和dictionaries)使用两种拷贝:浅拷贝和深拷贝。
 
浅拷贝创建一个新的对象,但是使用原来对象的元素的引用(如果是不变类型,相当于是拷贝)来填充新对象。可以使用copy.copy()来实现浅拷贝。

def TestShallowCopy():

    a = [ 1, 2, [3,4] ]

    b = list(a) # create a shallow copy of a

    print (b is a) #False

    b.append(100) #append element to b

    print (b)

    print (a) # a is unchanged

    b[2][0] = -100 # modify an element inside b

    print (b)

    print (a)  # a is changed

在这个例子中,a和b共享相同的可变元素。所以修改其中一个list对象中的元素,另一个list对象也会被修改。

深拷贝创建一个新的对象,同时递归地拷贝对象所包含的所有的元素。可以使用copy.deepcopy()来实现深拷贝。

def TestDeepCopy():

  import copy

  a = [1, 2, [3, 4]]

  b = copy.deepcopy(a)

  b[2][0] = -100

  print (b)  # b is changed

  print (a)  # a is unchanged

在这个例子中,a和b是对立的list对象,且他们的元素也相互独立。

三、引用计数和垃圾回收

python中的所有的对象都是引用计数的,一个对象赋值或加入容器时,它的引用计数就会自增,当使用del时或变量赋值为其他值时,引用计数就会自减,当引用计数为0时,python的垃圾回收器就会回收该变量。

def TestGarbageCollection():

  import sys

  print(sys.getrefcount(37))

  a = 37 # Creates an object with value 37

  print(sys.getrefcount(37))

  b = a # Increases reference count on 37

  print(sys.getrefcount(37))

  c = []

  c.append(b) # Increases reference count on 37

  print(sys.getrefcount(37))

  del a # Decrease reference count of 37

  print(sys.getrefcount(37))

  b = 42 # Decrease reference count of 37

  print(sys.getrefcount(37))

  c[0] = 2.0 # Decrease reference count of 37

  print(sys.getrefcount(37)) 

  

TestGarbageCollection()

运行结果为:

11

12

13

14

13

12

11

为啥一上来就有11个引用了呢?谁知道?
Python 相关文章推荐
python 提取文件的小程序
Jul 29 Python
Python中死锁的形成示例及死锁情况的防止
Jun 14 Python
使用Python操作excel文件的实例代码
Oct 15 Python
浅谈numpy库的常用基本操作方法
Jan 09 Python
Python实现抢购IPhone手机
Feb 07 Python
python从子线程中获得返回值的方法
Jan 30 Python
pycharm 2019 最新激活方式(pycharm破解、激活)
Sep 22 Python
keras .h5转移动端的.tflite文件实现方式
May 25 Python
Python获取android设备cpu和内存占用情况
Nov 15 Python
TensorFlow的环境配置与安装方法
Feb 20 Python
python获取淘宝服务器时间的代码示例
Apr 22 Python
python超详细实现完整学生成绩管理系统
Mar 17 Python
python实现的文件夹清理程序分享
Nov 22 #Python
Python判断操作系统类型代码分享
Nov 22 #Python
python logging类库使用例子
Nov 22 #Python
Python中模拟enum枚举类型的5种方法分享
Nov 22 #Python
Python读写Excel文件方法介绍
Nov 22 #Python
Python中的包和模块实例
Nov 22 #Python
Python动态加载模块的3种方法
Nov 22 #Python
You might like
用PHP生成html分页列表的代码
2007/03/18 PHP
PHP正确配置mysql(apache环境)
2011/08/28 PHP
Smarty保留变量用法分析
2016/05/23 PHP
微信 getAccessToken方法详解及实例
2016/11/23 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
Yii Framework框架使用PHPExcel组件的方法示例
2019/07/24 PHP
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
JavaScript中Math对象使用说明
2008/01/16 Javascript
11款新鲜的jQuery插件[附所有demo下载]
2011/01/24 Javascript
ajax请求get与post的区别总结
2013/11/04 Javascript
Javascript+CSS实现影像卷帘效果思路及代码
2014/10/20 Javascript
基于js中的原型、继承的一些想法
2016/08/10 Javascript
localStorage的黑科技-js和css缓存机制
2017/02/06 Javascript
bootstrap table实现单击单元格可编辑功能
2017/03/28 Javascript
jQuery实现按比例缩放图片的方法
2017/04/29 jQuery
vue 封装自定义组件之tabal列表编辑单元格组件实例代码
2017/09/07 Javascript
Angular5给组件本身的标签添加样式class的方法
2018/04/07 Javascript
vue实现图片上传到后台
2020/06/29 Javascript
python2.7删除文件夹和删除文件代码实例
2013/12/18 Python
Python打印scrapy蜘蛛抓取树结构的方法
2015/04/08 Python
在Python中使用lambda高效操作列表的教程
2015/04/24 Python
Python整型运算之布尔型、标准整型、长整型操作示例
2017/07/21 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
python爬取m3u8连接的视频
2018/02/28 Python
python绘制双Y轴折线图以及单Y轴双变量柱状图的实例
2019/07/08 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
jupyter lab文件导出/下载方式
2020/04/22 Python
通过实例解析Python文件操作实现步骤
2020/09/21 Python
html5设计原理(推荐收藏)
2014/05/17 HTML / CSS
英国天然抗衰老护肤品品牌:Nakin Skin Care
2019/04/16 全球购物
北京-环亚运商测试题.net程序员初步测试题
2013/05/28 面试题
联谊会主持词
2014/03/26 职场文书
国际贸易本科毕业生求职信
2014/09/26 职场文书
2014年人事工作总结范文
2014/11/19 职场文书
民事起诉书范本
2015/05/19 职场文书
安装Windows Server 2012 R2企业版操作系统并设置好相关参数
2022/04/29 Servers