python--__del__析构函数(二十六)

网友投稿 691 2022-05-29

Python--__del__析构函数(二十六)

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

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

引用计数吧。

1.引用计数

import sys

class MyClass(object):

def __init__(self):

python--__del__析构函数(二十六)

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。

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。

转载自:https://blog.csdn.net/wwh578867817/article/details/45398187

Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:你想学习做硬件?
下一篇:后端再进阶一步,MySQL 优化学习第1天
相关文章