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正则匹配查询港澳通行证办理进度示例分享
Dec 27 Python
Python多进程同步简单实现代码
Apr 27 Python
利用python实现数据分析
Jan 11 Python
python 删除大文件中的某一行(最有效率的方法)
Aug 19 Python
python+tkinter实现学生管理系统
Aug 20 Python
python django中8000端口被占用的解决
Dec 17 Python
python实现名片管理器的示例代码
Dec 17 Python
pycharm新建Vue项目的方法步骤(图文)
Mar 04 Python
TensorFlow固化模型的实现操作
May 26 Python
Django如何重置migration的几种情景
Feb 24 Python
解决Django transaction进行事务管理踩过的坑
Apr 24 Python
python之np.argmax()及对axis=0或者1的理解
Jun 02 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/09/30 PHP
php 中的4种标记风格介绍
2012/05/10 PHP
PHP实现多进程并行操作的详解(可做守护进程)
2013/06/18 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
jquery 多行滚动代码(附详细解释)
2010/06/17 Javascript
jQuery提交表单ajax查询实例代码
2012/10/07 Javascript
基于jQuery中对数组进行操作的方法
2013/04/16 Javascript
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
jQuery $.extend()用法总结
2014/06/15 Javascript
JS+CSS实现下拉刷新/上拉加载插件
2017/03/31 Javascript
微信小程序 实例开发总结
2017/04/26 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
2017/11/21 Javascript
JavaScript私有变量实例详解
2019/01/24 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
Vue-axios-post数据后端接不到问题解决
2020/01/09 Javascript
jQuery加PHP实现图片上传并提交的示例代码
2020/07/16 jQuery
解决vue addRoutes不生效问题
2020/08/04 Javascript
vue 调用 RESTful风格接口操作
2020/08/11 Javascript
Echarts在Taro微信小程序开发中的踩坑记录
2020/11/09 Javascript
python中将阿拉伯数字转换成中文的实现代码
2011/05/19 Python
Python重新引入被覆盖的自带function
2014/07/16 Python
python实现单线程多任务非阻塞TCP服务端
2017/06/13 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
Html5游戏开发之乒乓Ping Pong游戏示例(三)
2013/01/21 HTML / CSS
Weekendesk意大利:探索多种引人入胜的周末主题
2016/10/14 全球购物
教师实习自我鉴定
2013/12/11 职场文书
人力资源求职信
2014/05/25 职场文书
幼儿园教师节演讲稿
2014/09/03 职场文书
村干部四风问题整改措施
2014/09/30 职场文书
关于童年的读书笔记
2015/06/26 职场文书
有关朝花夕拾的读书笔记
2015/06/29 职场文书
缅怀先烈主题班会
2015/08/14 职场文书
大学优秀学生主要事迹材料
2015/11/04 职场文书
人事部:年度述职报告范文
2019/07/12 职场文书
互联网的下一个风口:新的独角兽将诞生
2019/08/02 职场文书
判断Python中的Nonetype类型
2021/05/25 Python