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 23 Python
wxPython使用系统剪切板的方法
Jun 16 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
Aug 30 Python
Python中的is和==比较两个对象的两种方法
Sep 06 Python
Python3解决棋盘覆盖问题的方法示例
Dec 07 Python
python实现决策树、随机森林的简单原理
Mar 26 Python
Python实现的从右到左字符串替换方法示例
Jul 06 Python
python使用turtle绘制国际象棋棋盘
May 23 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
Jun 12 Python
python RC4加密操作示例【测试可用】
Sep 26 Python
结合OpenCV与TensorFlow进行人脸识别的实现
Oct 10 Python
Python 如何调试程序崩溃错误
Aug 03 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
Laravel5.4框架中视图共享数据的方法详解
2019/09/05 PHP
asp.net+jquery滚动滚动条加载数据的下拉控件
2010/06/25 Javascript
JS正则中的RegExp对象对象
2012/11/07 Javascript
解析使用js判断只能输入数字、字母等验证的方法(总结)
2013/05/14 Javascript
今天是星期几的4种JS代码写法
2013/09/17 Javascript
JQuery each()嵌套使用小结
2014/04/18 Javascript
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
javascript比较两个日期相差天数的方法
2015/07/23 Javascript
JavaScript调用客户端Java程序的方法
2015/07/27 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
2016/07/14 Javascript
JavaScript条件判断_动力节点Java学院整理
2017/06/26 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
JavaScript使用FileReader实现图片上传预览效果
2020/03/27 Javascript
Angular CLI 安装和使用教程
2017/09/13 Javascript
js传递数组参数到后台controller的方法
2018/03/29 Javascript
ES6与CommonJS中的模块处理的区别
2018/06/13 Javascript
mpvue性能优化实战技巧(小结)
2019/04/17 Javascript
Javascript通过控制类名更改样式
2019/05/24 Javascript
js使用cookie实现记住用户名功能示例
2019/06/13 Javascript
通过Py2exe将自己的python程序打包成.exe/.app的方法
2018/05/26 Python
对python Tkinter Text的用法详解
2018/10/11 Python
Pytorch Tensor的索引与切片例子
2019/08/18 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
python+gdal+遥感图像拼接(mosaic)的实例
2020/03/10 Python
python urllib和urllib3知识点总结
2021/02/08 Python
做一个能自适应高度的textarea的示例代码
2019/09/06 HTML / CSS
销售所有的狗狗产品:Dog.com
2016/10/13 全球购物
汤米巴哈马官方网站:Tommy Bahama
2017/05/13 全球购物
马来西亚领先的在线礼品店:Giftr
2018/08/23 全球购物
北大自主招生自荐信
2013/10/19 职场文书
幼儿园教师教育感言
2014/02/28 职场文书
纪念九一八事变演讲稿:勿忘国耻
2014/09/14 职场文书
高三复习计划
2015/01/19 职场文书
致运动员加油稿
2015/07/21 职场文书
爱国之歌(8首)
2019/09/29 职场文书
Python 实现定积分与二重定积分的操作
2021/05/26 Python