1.首先介绍下python的对象引用

1)Python中不存在传值调用,一切传递的都是对象引用,也可以认为是传址调用。即Python不允许程序员选择采用传值或传引用。Python参数传递采用的是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数参数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过"传值"来传递对象。
2)当复制列表或字典时,就复制了对象列表的引用,如果改变引用的值,则修改了原始的参数。
3)为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。

2. 可变对象与不可变对象的概念与分类

Python在heap中分配的对象分成2类:

不可变对象(immutable object):Number(int、float、bool、complex)、String、Tuple. 采用等效于“传引用”的方式。

可变对象(mutable object):List、dictionary.采用等效于“传值”的方式。

Python的数据类型和c不太一样,有一种分类标准,可变(mutable)/不可变(immutable).
我理解的可变,就是在内存中的那块内容(value)是否可以被改变。如果是不可变的,在对对象本身操作的时候,必须在内存的另外地方再申请一块区域(因为老区域#不可变#),老的区域就丢弃了(如果还有其他ref,则ref数字减1,类似unix下的hard-link)。如果是可变的,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

#!/usr/bin/evn python
# -*- coding:utf-8 -*-
# Author: antcolonieslist1 = [1, 2, 3]
list2 = list1
list3 = list1
print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
'''
list1= [1, 2, 3]
list2= [1, 2, 3]
list3= [1, 2, 3]
id(list1)= 35456648
id(list2)= 35456648
id(list3)= 35456648
'''list2 = list2 + [4]      # 不可变类型操作
print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
'''
list1= [1, 2, 3]
list2= [1, 2, 3, 4]
list3= [1, 2, 3]
id(list1)= 35456648
id(list2)= 35455304
id(list3)= 35456648
''''''
>>> var1 = 1
>>> var2 = var1
>>> var1,var2
(1, 1)
>>> id(var1),id(var2)     # 地址1782298288的引用为2
(1782298288, 1782298288)
>>> var1 += 1             # 地址1782298288的引用为2-1=1
>>> var1,var2
(2, 1)
>>> id(var1),id(var2)
(1782298320, 1782298288)
>>>
'''list3 += [4]             # 可变类型操作
print('list1=', list1, '\nlist2=', list2, '\nlist3=', list3)
print('id(list1)=', id(list1), '\nid(list2)=', id(list2), '\nid(list3)=', id(list3))
'''
list1= [1, 2, 3, 4]
list2= [1, 2, 3, 4]
list3= [1, 2, 3, 4]
id(list1)= 35456648
id(list2)= 35455304
id(list3)= 35456648
'''

3. del 是删除引用而不是删除对象,对象由自动垃圾回收机制(GC)删除

看这个例子:

>>> x = 1
>>> del x
>>> x
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    x
NameError: name 'x' is not defined
>>> x = ['Hello','world']
>>> y = x
>>> y
['Hello', 'world']
>>> x
['Hello', 'world']
>>> del x
>>> x
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
x
NameError: name 'x' is not defined
>>> y
['Hello', 'world']
>>>

可以看到x和y指向同一个列表,但是删除x后,y并没有受到影响。这是为什么呢?
The reason for this is that you only delete the name,not the list itself,In fact ,there is no way to delete values in python(and you don’t really need to because the python interpreter does it by itself whenever you don’t use the value anymore)
 举个例子,一个数据(比如例子中的列表),就是一个盒子,我们把它赋给一个变量x,就是好像把一个标签x贴到了盒子上,然后又贴上了y,用它们来代表这个数据,但是用del删除这个变量x就像是把标有x的标签给撕了,剩下了y的标签。
再看一个例子:
shoplist = ['apple', 'mango', 'carrot', 'banana']
print ('The first item I will buy is', shoplist[0])
olditem = shoplist[0]
del shoplist[0]  #del的是引用,而不是对象
print ('I bought the',olditem)
print ('My shopping list is now', shoplist)
print(shoplist[0])
结果为:
The first item I will buy is apple
I bought the apple
My shopping list is now ['mango', 'carrot', 'banana']
mango

实例补充:

#!/usr/bin/evn python
# -*- coding:utf-8 -*-
# Author: antcolonies
'''
python中的内置方法del不同于C语言中的free和C++中的delete(free和delete直接回收内存,当然存储于该内存的对象也就挂了)
Python都是引用,垃圾回收为GC机制
''''''
if __name__ == '__main__':a = 1          # 对象 1 被 变量a引用,对象1的引用计数器为1b = a          # 对象1 被变量b引用,对象1的引用计数器加1c = a          # 对象1 被变量c引用,对象1的引用计数器加1del a          # 删除变量a,解除a对1的引用,对象1的引用计数器减1del b          # 删除变量b,解除b对1的引用,对象1的引用计数器减1print(c)       # 1
'''if __name__=='__main__':li=['one','two','three','four','five']  # 列表本身不包含数据'one','two','three','four','five',而是包含变量:li[0] li[1] li[2] li[3] li[4]first=li[0]       # 拷贝列表,也不会有数据对象的复制,而是创建新的变量引用del li[0]print(li)         # ['two','three','four','five']print(first)      # onelist1 = lidel liprint(list1)      # ['two', 'three', 'four', 'five']
#   print(type(li))   # NameError: name 'li' is not defined

转载于:https://www.cnblogs.com/ant-colonies/p/6602742.html

Python对象引用和del删除引用相关推荐

  1. Python编程学习3:Python 对象引用和 del 删除引用

    面试遇到一个问题:如何删除一个python对象? 下面将介绍python的对象引用和 del删除引用 1.  首先介绍下python的对象引用 1)Python中不存在传值调用,一切传递的都是对象引用 ...

  2. python对象一定要删除引用吗_Python:删除自引用对象

    我想问一下如何在Python中删除带有自引用的对象.在 让我们考虑一个类,这是一个简单的示例,可以知道它何时创建和何时删除:#!/usr/bin/python class TTest: def __i ...

  3. python对象一定要删除引用吗_在Python中删除一个对象和所有对它的引用?

    如果我理解正确,你将包装一些C代码,并且C代码有一个可以被调用的析构函数.之后,任何使用指向C代码对象的指针的尝试都会导致致命的崩溃. 我不确定你的具体情况,所以我将给你两个替代答案. 0)如果C对象 ...

  4. Python中的变量、引用、拷贝和作用域

    在Python中,变量是没有类型的,这和以往看到的大部分编辑语言都不一样.在使用变量的时候,不需要提前声明,只需要给这个变量赋值即可.但是,当用变量的时候,必须要给这个变量赋值:如果只写一个变量,而没 ...

  5. python删除元素del 可以删除部分元素吗_可以使用del删除集合中的部分元素。

    [判断题]Python集合可以包含相同的元素.(3.0分) [单选题]student = dict(姓名='张三', 年龄=20, 性别='男'),则student.get("name&qu ...

  6. python实现链表的删除_Python垃圾回收机制

    python作为一门解释型语言,以代码简洁易懂著称.我们可以直接对名称赋值,而不必声明类型.名称类型的确定.内存空间的分配与释放都是由python解释器在运行时进行的.python这一自动管理内存功能 ...

  7. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

  8. Python中的del用法

    python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...

  9. python 中的 del 使用方法

    python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...

最新文章

  1. 在linux挂载网络驱动器,利用centos 6.6 搭建iscsi服务器并在centos挂载iscsi网络驱动器...
  2. php导出数据库的指定表数据,MYSQL教程mysql数据库导出指定表数据的方法
  3. 真格量化——GFTD策略
  4. 踏上Silverlight的征程 体验Silverlight之美
  5. Python 函数定义
  6. numpy—np.argpartition
  7. 无盘工作站建立全攻略
  8. 【应用随机过程】01. 随机过程的基本概念
  9. ArcGIS上海市行政区划图制作(附练习数据下载)
  10. python并发编程gevent模块以及猴子补丁学习
  11. 【我的Android进阶之旅】解决使用DiskLruCache报错: keys must match regex [a-z0-9_-]{1,64}
  12. tosmana使用教程_20款最流行的免费定性数据分析工具
  13. PHP留言板 PHP在线咨询留言系统
  14. 第2次作业:微信案例分析
  15. 纳米数据世界杯足球数据api接口,体育数据api接口,实时比分接口示例演示,数据推送
  16. 关于九宫格的一个算法,求大神助攻
  17. ai画面怎么调大小_AI中怎么才能把图像等比例扩大或缩小尺寸?
  18. 海信智慧黑板Android版本,海信智慧黑板,给老师减负,再也不用“喝”粉笔末了...
  19. javascript 获取具体id
  20. 随元素而来,随元素而去,变一变样式,深藏功与名——论伪元素

热门文章

  1. 微软对 Windows 10 Mobile 的支持将于12月10日结束
  2. web里如何在背景图片上放置div元素_2020年web前端开发经典面试题总结整理(建议收藏)...
  3. html怎么增加td的宽度,html td怎么设置宽度
  4. python基础试题选择题_附带答案的15道经典python基础面试题
  5. oracle常用系统变量,Oracle环境变量
  6. oracle有没有mysql if_Oracle中没有 if exists(...)
  7. uniapp 自动播放背景音乐
  8. 保时捷服务器连接不到车辆信息,检修保时捷老款卡宴无法启动故障
  9. seata使用报错no available service found in cluster ‘default‘
  10. bootstrap怎么强制不换行_【Word考点】页面设置:页边距、分隔符要怎么设置?如何分栏?...