对象析构函数__del__在Python中何时使用


Posted in Python onMarch 22, 2022

对象析构函数__del__在Python中何时使用

前言:

Python 中的类的构造函数 ​​__init__​​ , 每当实例产生就会调用这个构造函数。

反过来,每当实例对象需要被垃圾收集被收回时,就需要用到析构函数 ​​__del__​​ 。

​​__del__​​ 方法是类的一种特殊方法。可以利用 ​​__del__​​ 方法来清理资源,例如关闭文件。

来看一个例子:

class Life:

    def __init__(self, name='None'):
        print('Hello,' + name)
        self.name = name

    def live(self):
        print(self.name)
    
    def __del__(self):
        print("Goodbye," + self.name)

def main():

    bob = Life('Bob')
    bob.live()

if __name__ == '__main__':
    main()

运行该代码,输出结果为:

Hello,Bob
Bob
Goodbye,Bob

我们得到上面的输出是因为当代码即将结束时,不再需要类 Life,因此它已准备好被销毁。 在类 Life 被销毁之前,会自动调用 ​​__del__​​ 方法。

还可以通过调用 ​​del​​ 手动调用 ​​__del__​​ 方法:

class Life:

    def __init__(self, name='None'):
        print('Hello,' + name)
        self.name = name

    def live(self):
        print(self.name)
    
    def __del__(self):
        print("Goodbye," + self.name)

def main():

    bob = Life('Bob')
    del bob

if __name__ == '__main__':
    main()

执行结果:

Hello,Bob
Goodbye,Bob

值得注意的是:​​del x​​ 并不直接调用 ​​x.__del__()​​ ,前者将 x 的引用计数减一,而后者仅在其引用计数达到零时才被调用。

在 Python 中,任何未使用的对象(如内置类型或类的实例)在不再使用时会自动从内存中删除(移除)。 这种释放和回收未使用内存空间的过程称为垃圾回收。

在Python中何时使用__del__?

重要的是要注意,当对象处于销毁的过程中,调用 ​​__del__​​ 方法(未损坏后),因此仍然可以在__del__方法中访问属性。

由于​​__del__​​ 可以访问对象的数据成员,因此应该确保对象的填充删除,以便没有内存泄露。

class App:
    def __init__(self):
        print("Open App")

    def __del__(self):
        print("Closed App")

class Phone:
    app = None

    def __init__(self):
        print("Switching on the Phone")
        self.__class__.app = App()

    def __del__(self):
        del self.__class__.app
        print("Switching off the Phone")

phone = Phone()

del phone

执行结果:

Switching on the Phone
Open App
Closed App
Switching off the Phone

在这个例子中,如果我们没有在​​__del__​​ 方法中销毁手机的属性 app,它就会留在内存中,导致内存泄漏。

析构函数使用紧要

Python 中的析构函数并不像 C++ 中那样被频繁使用,因为它存在一些众所周知的警告和极少数鲜为人知的暗坑。

尽量减少使用 ​​__del__​​ 函数:

  • 第一,因为 Python 在回收实例时,会自动回收该实例拥有的所有内存空间,所以析构函数并不需要考虑空间管理。所以也就失去了手动写 ​​__del__​​ 的意义。
  • 第二,无法预测一个实例什么时候会被回收。有时候你想触发析构函数时,系统表中对对象的引用会阻止析构函数的执行。Python 也无法保证解释器退出时,一个仍然存在的对象会调用其析构函数。
  • 第三,​​__del__​​ 可能会引发的异常会直接向 sys.stderr(标准错误流) 打印一条警告消息,而不是触发一个异常事件。因为它通过垃圾收集器运行在不可预料的上下文中。
  • 第四,当我们期待垃圾回收时,对象间的循环引用可能会阻止其发生。

总结:

  • 当对象被销毁时,Python 会自动调用对象上的 ​​__del__​​ 方法(​​类似于在对象创建期间调用的 ​​__init__​​ 构造函数)。
  • ​​__del__​​ 方法类似于 C++ 和 Java 中的析构函数。用于销毁对象的状态。
  • Python 中,尽量减少析构函数的使用。

到此这篇关于Python 中的对象析构函数__del__ 详情的文章就介绍到这了,更多相关Python 对象析构函数del内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python高级应用实例对比:高效计算大文件中的最长行的长度
Jun 08 Python
Python使用百度API上传文件到百度网盘代码分享
Nov 08 Python
python操作ssh实现服务器日志下载的方法
Jun 03 Python
基于python实现微信模板消息
Dec 21 Python
python条件变量之生产者与消费者操作实例分析
Mar 22 Python
Python实现螺旋矩阵的填充算法示例
Dec 28 Python
Python代码缩进和测试模块示例详解
May 07 Python
使用Python更换外网IP的方法
Jul 09 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
Jan 15 Python
wxpython多线程防假死与线程间传递消息实例详解
Dec 13 Python
python获取时间戳的实现示例(10位和13位)
Sep 23 Python
python中类与对象之间的关系详解
Dec 16 Python
详解Python内置模块Collections
Mar 22 #Python
Python中 range | np.arange | np.linspace三者的区别
Python中非常使用的6种基本变量的操作与技巧
python使用torch随机初始化参数
Mar 22 #Python
Django基础CBV装饰器和中间件
详解pytorch创建tensor函数
Mar 22 #Python
详解Python+OpenCV绘制灰度直方图
You might like
老照片 - 几十年前的收音机与人
2021/03/02 无线电
如何使用PHP往windows中添加用户
2006/12/06 PHP
PHP学习笔记之一
2011/01/17 PHP
深入PHP数据缓存的使用说明
2013/05/10 PHP
php定时计划任务的实现方法详解
2013/06/06 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
2016/05/06 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
RR vs IO BO3 第二场2.13
2021/03/10 DOTA
js 解决“options为空或不是对象”
2008/12/22 Javascript
文本框的字数限制功能jquery插件
2009/11/24 Javascript
防止文件缓存的js代码
2013/01/10 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
jtable列中自定义button示例代码
2013/11/21 Javascript
利用javascript打开模态对话框(示例代码)
2014/01/11 Javascript
JQuery打造省市下拉框联动效果
2014/05/18 Javascript
告诉你什么是javascript的回调函数
2014/09/04 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
2016/01/05 Javascript
JS中判断null的方法分析
2016/11/21 Javascript
概述jQuery中的ajax方法
2016/12/16 Javascript
移动端界面的适配
2017/01/11 Javascript
AngularJS改变元素显示状态
2017/04/20 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
手把手教你用python抢票回家过年(代码简单)
2018/01/21 Python
Python图片处理模块PIL操作方法(pillow)
2020/04/07 Python
解析Python 偏函数用法全方位实现
2020/06/26 Python
Python中Selenium库使用教程详解
2020/07/23 Python
德国自然时尚和有机产品购物网站:Waschbär
2019/05/29 全球购物
什么是接口(Interface)?
2013/02/01 面试题
C#和SQL Server的面试题
2016/08/12 面试题
介绍JAVA 中的Collection FrameWork(及如何写自己的数据结构)
2014/10/31 面试题
保险专业大专生求职信
2013/10/26 职场文书
初中新生军训方案
2014/05/13 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
Mysql 设置boolean类型的操作
2021/06/04 MySQL
JavaScript数组 几个常用方法总结
2021/11/11 Javascript