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程序的循环的运行效率的原因
Apr 01 Python
Python中Class类用法实例分析
Nov 12 Python
python简单商城购物车实例代码
Mar 15 Python
python将文本分每两行一组并保存到文件
Mar 19 Python
Python字符串逆序的实现方法【一题多解】
Feb 18 Python
python获取磁盘号下盘符步骤详解
Jun 19 Python
Django和Flask框架优缺点对比
Oct 24 Python
Django认证系统user对象实现过程解析
Mar 02 Python
Python+kivy BoxLayout布局示例代码详解
Dec 28 Python
pyspark对Mysql数据库进行读写的实现
Dec 30 Python
python实现股票历史数据可视化分析案例
Jun 10 Python
python代码实现扫码关注公众号登录的实战
Nov 01 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保留两位小数并且四舍五入及不四舍五入的方法
2013/09/22 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
js 判断 enter 事件
2009/02/12 Javascript
Javascript 键盘keyCode键码值表
2009/12/24 Javascript
Javascript学习笔记8 用JSON做原型
2010/01/11 Javascript
过虑特殊字符输入的js代码
2010/08/05 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
JavaScript中数组对象的那些自带方法介绍
2013/03/12 Javascript
jQuery 中$(this).index与$.each的使用指南
2014/11/20 Javascript
node.js中的path.isAbsolute方法使用说明
2014/12/08 Javascript
javascript实现密码强度显示
2015/03/18 Javascript
jQuery+ajax实现文章点赞功能的方法
2015/12/31 Javascript
基于jquery fly插件实现加入购物车抛物线动画效果
2016/04/05 Javascript
JS实现兼容各种浏览器的获取选择文本的方法【测试可用】
2016/06/21 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
2016/08/15 Javascript
微信小程序合法域名配置方法
2019/05/06 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
python利用elaphe制作二维条形码实现代码
2012/05/25 Python
使用Python写CUDA程序的方法
2017/03/27 Python
python删除过期log文件操作实例解析
2018/01/31 Python
说说如何遍历Python列表的方法示例
2019/02/11 Python
解决python3 安装不了PIL的问题
2019/08/16 Python
Python生成器常见问题及解决方案
2020/03/21 Python
使用HTML5原生对话框元素并轻松创建模态框组件
2019/03/06 HTML / CSS
会计实习期自我鉴定
2013/10/06 职场文书
执行总经理岗位职责
2014/02/03 职场文书
人力资源部经理助理岗位职责
2014/03/04 职场文书
岗位廉洁从业承诺书
2014/03/28 职场文书
交通事故协议书范文
2014/10/23 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
2014年汽车销售工作总结
2014/12/01 职场文书
个人先进事迹材料
2014/12/29 职场文书
初中开学典礼新闻稿
2015/07/17 职场文书
小学生节约用水倡议书
2019/08/12 职场文书
CSS3 制作的图片滚动效果
2021/04/14 HTML / CSS
详解Redis主从复制实践
2021/05/19 Redis