今天学习面向对象里的类被del函数的垃圾回收过程搞的晕头转向,经过了老师的讲解还是是懂非懂,然后看了很多博客慢慢的心里才有了个大概的了解。

刚刚看到一篇博客,觉得讲的很好,转载过来以供参考。以下转自笨笨D幸福博客:http://blog.csdn.net/bbdxf/article/details/25774763

探索过程:

1、经过查找,Python中没有专用的构造和析构函数,但是一般可以在__init__和__del__分别完成初始化和删除操作,可用这个替代构造和析构。还有一个__new__用来定制类的创建过程,不过需要一定的配置,此处不做讨论。

2、类的成员函数默认都相当于是public的,但是默认开头为__的为私有变量,虽然是私有,但是我们还可以通过一定的手段访问到,即Python不存在真正的私有变量。如:

01.__priValue = 0 # 会自动变形为"_类名__priValue"的成员变量  

3、由于Python的特殊性,全局成员变量是共享的,所以类的实例不会为它专门分配内容空间,类似于static,具体使用参看下面的例子。

测试1:

01.# encoding:utf8
02.
03.class NewClass(object):
04. num_count = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
05. def __init__(self,name):
06. self.name = name
07. NewClass.num_count += 18. print name,NewClass.num_count
09. def __del__(self):
10. NewClass.num_count -= 1
11. print "Del",self.name,NewClass.num_count
12. def test():
13. print "aa"
14.
15.aa = NewClass("Hello")
16.bb = NewClass("World")
17.cc = NewClass("aaaa")
18.
19.print "Over"

调试运行:

01.Hello 1
02.World 2
03.aaaa 3
04.Over
05.DeException l Hello 2
06.AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF18D0>> ignored
07.Exception AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object

我们发现,num_count 是全局的,当每创建一个实例,__init__()被调用,num_count 的值增一,当程序结束后,所有的实例会被析构,即调用__del__() 但是此时引发了异常。查看异常为 “NoneType” 即 析构时NewClass 已经被垃圾回收,所以会产生这样的异常。

但是,疑问来了?为什么会这样?按照C/C++等语言的经验,不应该这样啊!经过查找资料,发现:

Python的垃圾回收过程与常用语言的不一样,Python按照字典顺序进行垃圾回收,而不是按照创建顺序进行。所以当系统进行回收资源时,会按照类名A-Za-z的顺序,依次进行,我们无法掌控这里的流程。

明白这些,我们做如下尝试:

01.# encoding:utf8
02.
03.class NewClass(object):
04. num_count = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
05. def __init__(self,name):
06. self.name = name
07. NewClass.num_count += 18. print name,NewClass.num_count
09. def __del__(self):
10. NewClass.num_count -= 1
11. print "Del",self.name,NewClass.num_count
12. def test():
13. print "aa"
14.
15.aa = NewClass("Hello")
16.bb = NewClass("World")
17.cc = NewClass("aaaa")
18.
19.del aa
20.del bb
21.del cc
22.
23.print "Over"

调试输出:

01.Hello 1
02.World 2
03.aaaa 3
04.Del Hello 2
05.Del World 1
06.Del aaaa 0
07.Over

OK,一切按照我们预料的顺序发生。

但是,我们总不能每次都手动回收吧?这么做Python自己的垃圾回收还有什么意义?

SO,继续查找,我们还可以通过self.__class__访问到类本身,然后再访问自身的共享成员变量,即 self.__class__.num_count , 将类中的NewClass.num_count替换为self.__class__.num_count 编译运行,如下:

01.# encoding:utf8
02.
03.class NewClass(object):
04. num_count = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
05. def __init__(self,name):
06. self.name = name
07. self.__class__.num_count += 18. print name,NewClass.num_count
09. def __del__(self):
10. self.__class__.num_count -= 1
11. print "Del",self.name,self.__class__.num_count
12. def test():
13. print "aa"
14.
15.aa = NewClass("Hello")
16.bb = NewClass("World")
17.cc = NewClass("aaaa")
18.
19.print "Over"

结果:

01.Hello 1
02.World 2
03.aaaa 3
04.Over
05.Del Hello 2
06.Del World 1
07.Del aaaa 0

python中del函数的垃圾回收的更多相关文章

  1. 【Python】Python中对象管理与垃圾回收中两个很有意思的问题

    再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两 ...

  2. 【python进阶】Garbage collection垃圾回收2

    前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...

  3. python的 del 函数是删对象还是删引用

    1.首先介绍下python的对象引用 1)Python中不存在传值调用,一切传递的都是对象引用,也可以认为是传址调用.即Python不允许程序员选择采用传值或传引用.Python参数传递采用的是“传对 ...

  4. python的优化机制与垃圾回收与gc模块

    python属于动态语言,我们可以随意的创建和销毁变量,如果频繁的创建和销毁则会浪费cpu,那么python内部是如何优化的呢? python和其他很多高级语言一样,都自带垃圾回收机制,不用我们去维护 ...

  5. Python的内存管理和垃圾回收机制

    内存管理 Python解释器由c语言开发完成,py中所有的操作最终都由底层的c语言来实现并完成,所以想要了解底层内存管理需要结合python源码来进行解释. 1. 两个重要的结构体 include/o ...

  6. 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...

  7. Python中split()函数的用法及实际使用示例

    Python中split()函数,通常用于将字符串切片并转换为列表. 一.函数说明: split():语法:str.split(str="",num=string.count(st ...

  8. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  9. python中range()函数的用法

    python中range()函数可创建一个整数列表,一般用在for循环中. range()函数语法: range(start,stop[,step]) 参数说明: star: 计数从star开始.默认 ...

随机推荐

  1. arduino空调遥控器

    参考:http://www.arduino.cn/thread-3487-1-1.html http://www.arduino.cn/thread-3618-1-1.html 注意1:有金属外壳的一 ...

  2. pytest 简介与安装

    前面我们已经基本上掌握了unittest测试框架,下面我们将学习新的pytest测试框架.之于原因嘛,太流行啦!掌握一个框架是不够的,急需另外一个,于是瞅上了pytest. pytest是什么? py ...

  3. 几个经典的数学库之一学习---VCGlib(3)

    Camera and shot abstraction for managing views 视图的定义,以及mesh的操作说明. Shot(镜头) and camera(相机) shot摄像结构以及 ...

  4. node API assert

    1.assert.throws(block, [error], [message]): assert.throws( function(){ throw new Error('wrong'); }, ...

  5. Bitcoin

    看李笑来老师的2013演讲——Bitcoin is not virtual currency,it is a real world. 1.由于bitcoin的算法中进行有上限量的发布,所以这是不会出现 ...

  6. 再也不用线上倒数据了,使用 Faker 来造一批假的数据吧。

    背景每当建表之后,常常需要写一批假的数据,用于测试算法.数据量的压力测试.列表翻页. 查看详情.数据关联等.这时就需要借助一款造数据的工具,它就是今天所要介绍的 Faker. 介绍 Faker 这个工 ...

  7. Spring Boot 2 实践记录之 使用 ConfigurationProperties 注解将配置属性匹配至配置类的属性

    在 Spring Boot 2 实践记录之 条件装配 一文中,曾经使用 Condition 类的 ConditionContext 参数获取了配置文件中的配置属性.但那是因为 Spring 提供了将上 ...

  8. python中list的sort方法

    转:https://www.cnblogs.com/zle1992/p/6271105.html 使用python对列表(list)进行排序,说简单也简单,说复杂也复杂,我一开始学的时候也搞不懂在说什 ...

  9. JS和C#访问遇到QueryInterface调用出错

    在原来的WinForm里,我们只要在窗体类的头部添加属性[System.Runtime.InteropServices.ComVisibleAttribute(true)],然后 webBrowser ...

  10. Oracle数据库多行记录转换一行并排序函数

    Oracle数据库多行记录转换一行并排序方法 在ORACLE数据库查询中,我们通常会要求用到将多行记录转换成一行并排序,这时候我们自然会想到Oracle的一个“wx_concat”函数,可以将多行记录 ...