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中用Spark模块的使用教程
Apr 13 Python
浅谈pyhton学习中出现的各种问题(新手必看)
May 17 Python
Python OpenCV获取视频的方法
Feb 28 Python
Python爬虫实现(伪)球迷速成
Jun 10 Python
pycharm运行程序时在Python console窗口中运行的方法
Dec 03 Python
解决vscode python print 输出窗口中文乱码的问题
Dec 03 Python
windows系统中Python多版本与jupyter notebook使用虚拟环境的过程
May 15 Python
TensorFLow 变量命名空间实例
Feb 11 Python
解决Django Haystack全文检索为空的问题
May 19 Python
Python实现播放和录制声音的功能
Aug 12 Python
详解pycharm自动import所需的库的操作方法
Nov 30 Python
matplotlib绘制鼠标的十字光标的实现(内置方式)
Jan 06 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中的foreach问题
2013/06/30 PHP
php+js实现异步图片上传实例分享
2014/06/02 PHP
php表单敏感字符过滤类
2014/12/08 PHP
PHP自动载入类文件函数__autoload的使用方法
2019/03/25 PHP
laravel5.2表单验证,并显示错误信息的实例
2019/09/29 PHP
收集的10个免费的jQuery相册
2011/02/26 Javascript
jquery插件制作教程 txtHover
2012/08/17 Javascript
JavaScript中“过于”犀利地for/in循环使用示例
2013/10/22 Javascript
jQuery 鼠标经过(hover)事件的延时处理示例
2014/04/14 Javascript
20分钟轻松创建自己的Bootstrap站点
2016/05/12 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
2016/05/30 Javascript
JS实现图片放大缩小的方法
2017/02/15 Javascript
js实现京东轮播图效果
2017/06/30 Javascript
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
Vue 实现CLI 3.0 + momentjs + lodash打包时优化
2019/11/13 Javascript
基于小程序请求接口wx.request封装的类axios请求
2020/07/02 Javascript
js实现限定范围拖拽的示例
2020/10/26 Javascript
vue 使用class创建和清除水印的示例代码
2020/12/25 Vue.js
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
matplotlib中legend位置调整解析
2017/12/19 Python
Django框架使用内置方法实现登录功能详解
2019/06/12 Python
如何使用Python 打印各种三角形
2019/06/28 Python
python中的反斜杠问题深入讲解
2019/08/12 Python
Web前端绘制0.5像素的几种方法
2017/08/11 HTML / CSS
纯CSS3制作的简洁蓝白风格的登录模板(非IE效果更好)
2013/08/11 HTML / CSS
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
AJax面试题
2014/11/25 面试题
大学毕业感言
2014/01/10 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
幼儿园迎新生欢迎词
2015/09/30 职场文书
化工厂员工工作总结
2015/10/15 职场文书
幼儿教师继续教育培训心得体会
2016/01/19 职场文书
python tkinter模块的简单使用
2021/04/07 Python
2021年最新用于图像处理的Python库总结
2021/06/15 Python