码迷,mamicode.com
首页 > 编程语言 > 详细

python 的__del__删除器方法

时间:2015-04-30 21:57:57      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:python   脚本语言   内存   对象      

遇到了python关于del的小问题,又引发了一些问题,就简单的记录下,如果有不同意见,欢迎一起讨论~



python类似java是有垃圾回收机制的语言,所以我们不需要像c++一样通过析构函数来手动释放内存,

但是python也同样提供了__del__释放方法。当一个对象的引用计数为0时,会被自动调用,那么先来说说

引用计数吧。

1.引用计数

#!/usr/bin/env python
#coding:UTF-8

import sys

class MyClass(object):
    def __init__(self):
        print('i am __init__ function')

    def __del__(self):
        print('i am __del__ function')


if __name__ == '__main__':
    m1 = MyClass()
    m2 = m1
    print(sys.getrefcount(m1))

结果如下图:

技术分享

结果很让人吃惊吧,只有两个实例,为什么引用计数是3 ? 

都知道python是一门脚本语言,解释型语言,但是不知道大家有没有注意python其实也是有编译过程的。

.pyc文件就是个很好的证明。可以去/usr/lib/python看看

所以说的细致一点python是一门先编译后解释的语言,编译指的是编译成为字节码,然后然逐行解释字节码。

平时解释器帮我们做好了而已,你可能会说上面的代码怎么看不见.pyc文件呢,你把函数单独成一个.py文件

然后import导入后编译就可以看见了。其实.pyc文件只是编译后的 PyCodeObject存储在硬盘上的表现而已。

编译产生的真正的结果是PyCodeObject

过程.py ->编译 -> PyCodeObject ->解释(虚拟机执行)

现在说引用计数,绕了个弯,其实也不算,因为引用计数的值不对就是因为python的编译过程。


详情可参考http://blog.csdn.net/balabalamerobert/article/details/1649490


2.__del__


前面说了python的引用计数为0时会自动回收对象,所以一般是不推荐我们使用python中的__del__删除方法的

我在自己使用__del__过程中就遇到了一个问题,还是看代码:

定义了两个类,一个基类MyClass有名字和电话等信息,派生类DerClass添加了地址,每个类都有一个attribute属性

glb和der_glb。

#!/usr/bin/env python
#coding:UTF-8

class MyClass(object):
    glb = 100                #global variable
    def __init__(self, nm, ph):
        self.name = nm
        self.phone = ph

class DerClass(MyClass):
    der_glb = 200               #global variable
    def __init__(self, nm, ph, addr):
        super.__init__(nm, ph)                  #python3
        self.address = addr

    def __del__(self):
        #del self.__class__.der_glb
        del self.der_glb
        print 'del der_glb'

if __name__ == '__main__':
    m1 = MyClass('wwh', '123')
    m2 = DerClass('wwh', '456', 'xian')

主要看下del函数,我在del函数中自己调用了del self.der_glb来删除这个所有类共用的变量

(python中类内定义的变量所有实例共用)

结果报错了

技术分享

但是我改为del self.__class__.der_glb却正确了

这是什么原因呢

前面说了python中类内定义的变量所有实例共用,那么每个实例在结束后也就是自己的引用计数为0时都会被调用del

也就是说每个实例都del了一遍只有一份的der_glb变量,当然是不对的

那么为什么加上__class__就正确了呢

python的内存模型应该是我们定义了一个类后,这个类的模板module也会在内存中存储一份(id(Der_class)可证明),毕竟它还有所有实例需要用的变量等等。

所以__class__含义应该是获取到内存中这个module的地址,然后取得module的der_glb,删除它。

删除它后我们当然不能使用它了。

类似python的delattr(obj, attr)删除类的属性一样

在我按照上面所说的进行修改后,del self.__class__.der_glb,运行成功,并且再次定义类的实例时访问der_glb属性报错,报错结果如下:

技术分享

可见在del der_glb后,再次使用der_glb显示has no attibute ‘der_glb‘,证明前面我所说的是正确的,该属性已经被删除

说明一下python中的der_glb类似c++中的static变量,所有实例被共用,但是在python中被称为该类的属性attribute。


虽然python很好用,但是也需要搞清楚一些原理 ^_^






python 的__del__删除器方法

标签:python   脚本语言   内存   对象      

原文地址:http://blog.csdn.net/wwh578867817/article/details/45398187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!