今天学习面向对象里的类被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. git将本地仓库强制替换掉远程仓库

    $ git remote add origin <url> $ git push --force --set-upstream origin master

  2. if_elseif

    用MATLAB写了个这样的程序 if ((0 < pwr <=2) ) wf_temp1 = round(temp_wf0/2^7); elseif( (2 < pwr<= 4 ...

  3. 团队项目(第三周)—GG队

    需求改进&系统设计 队员 学号 叶尚文(队长) 3116008802 蔡晓晴 3216008808 杜婷萱 3216008809 龙剑初 3116004647 于泽浩 3116004661 一 ...

  4. Android SQLiteOpenHelper Sqlite数据库的创建与打开

    Android Sqlite数据库是一个怎样的数据库? 答:是一种嵌入式小型设备,移动设备,的数据库,应用在穿戴设备(例如:智能手表,计算手环 等等),移动设备(例如:Android系统类型的手机 等 ...

  5. Android 体系架构

    什么是Android? 答:Android就是移动设备的软件栈,包括(一个完整的操作系统,中间件,关键应用程序), 底层是Linux内核,包括(安全管理, 内存管理,进程管理 ,电源管理,硬件驱动-) ...

  6. 项目笔记---WPF之Metro风格UI

    写在前面 作为新年开篇的文章,当然要选择比较“Cool”的东西来分享,这自然落到了WPF身上,WPF技术自身可塑性非常强,其强大的绘图技术以及XAML技术比WinForm而言有本质的飞跃. 切入正题, ...

  7. Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization【转】

    https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Proto ...

  8. Java反射reflection与注解annotation的应用(自动测试机)

    一.关于自动测试机 1.什么是自动测试机? 对类中的指定方法进行批量测试的工具 2.自动测试机有什么用? a.避免了冗长的测试代码 当类中的成员方法很多时,对应的测试代码可能会很长,使用测试能够让测试 ...

  9. asp.net缓存使用介绍

    介绍: 在我解释cache管理机制时,首先让我阐明下一个观念:IE下面的数据管理.每个人都会用不同的方法去解决如何在IE在管理数据.有的会提到用状态管理,有的提到的cache管理,这里我比较喜欢cac ...

  10. FLV文件格式官方规范详解

    ——如果要学习一个新的知识点,官方手册可能是最快的途径.查看网上其他人的总结也许入门更快,但是要准确,深入,完整,还是要看官方手册.   以下内容来自对官方文档Video File Format Sp ...