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中使用smtplib和email模块发送邮件实例
Apr 22 Python
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
Jul 04 Python
Python中pip安装非PyPI官网第三方库的方法
Jun 02 Python
Python3使用requests登录人人影视网站的方法
May 11 Python
python pandas 如何替换某列的一个值
Jun 09 Python
Python中extend和append的区别讲解
Jan 24 Python
python 中如何获取列表的索引
Jul 02 Python
利用Python模拟登录pastebin.com的实现方法
Jul 12 Python
python @propert装饰器使用方法原理解析
Dec 25 Python
基于python实现计算两组数据P值
Jul 10 Python
Python 如何反方向迭代一个序列
Jul 28 Python
Python中time标准库的使用教程
Apr 13 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学习之变量的使用
2011/05/29 PHP
php中error与exception的区别及应用
2014/07/28 PHP
[原创]php求圆周率的简单实现方法
2016/05/30 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
PHP精确到毫秒秒杀倒计时实例详解
2019/03/14 PHP
jquery中ajax学习笔记3
2011/10/16 Javascript
jquery 实现checkbox全选,反选,全不选等功能代码(奇数)
2012/10/24 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
javascript实现阻止iOS APP中的链接打开Safari浏览器
2014/06/12 Javascript
js实现数字每三位加逗号的方法
2015/02/05 Javascript
JS生成某个范围的随机数【四种情况详解】
2016/04/20 Javascript
前后端如何实现登录token拦截校验详解
2018/09/03 Javascript
VUE搭建手机商城心得和遇到的坑
2019/02/21 Javascript
详解jquery和vue对比
2019/04/16 jQuery
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
Vue实现仿iPhone悬浮球的示例代码
2020/03/13 Javascript
python list使用示例 list中找连续的数字
2014/01/27 Python
仅用500行Python代码实现一个英文解析器的教程
2015/04/02 Python
详解python如何调用C/C++底层库与互相传值
2016/08/10 Python
python通过pip更新所有已安装的包实现方法
2017/05/19 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
2017/12/19 Python
Django中间件工作流程及写法实例代码
2018/02/06 Python
python使用pipeline批量读写redis的方法
2019/02/18 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
教你使用Sublime text3搭建Python开发环境及常用插件安装另分享Sublime text3最新激活注册码
2020/11/12 Python
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
入党积极分子思想汇报范文
2014/01/05 职场文书
期末评语大全
2014/05/04 职场文书
服装设计师求职信
2014/06/04 职场文书
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
支行行长岗位职责
2015/02/15 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
2015年资料员工作总结
2015/04/25 职场文书
追悼会家属答谢词
2015/09/29 职场文书
六年级上册《闻官军收河南河北》的教学设计
2019/11/15 职场文书