对象析构函数__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中的__new__()方法的使用
Apr 09 Python
在Python中使用判断语句和循环的教程
Apr 25 Python
六个窍门助你提高Python运行效率
Jun 09 Python
Python3 串口接收与发送16进制数据包的实例
Jun 12 Python
Python PyCharm如何进行断点调试
Jul 05 Python
Python Django 简单分页的实现代码解析
Aug 21 Python
pycharm通过ssh连接远程服务器教程
Feb 12 Python
在python3中实现查找数组中最接近与某值的元素操作
Feb 29 Python
Python如何使用正则表达式爬取京东商品信息
Jun 01 Python
基于python实现生成指定大小txt文档
Jul 20 Python
Python调用ffmpeg开源视频处理库,批量处理视频
Nov 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
DSP接收机前端设想
2021/03/02 无线电
黑夜路人出的几道php笔试题
2009/08/04 PHP
PHP 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
PHP Global定义全局变量使用说明
2013/08/15 PHP
CI框架实现优化文件上传及多文件上传的方法
2017/01/04 PHP
ThinkPHP删除栏目(实现批量删除栏目)
2017/06/21 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
PHP中echo与print区别点整理
2021/03/09 PHP
js算法中的排序、数组去重详细概述
2013/10/14 Javascript
js实现编辑div节点名称的方法
2014/12/17 Javascript
javaScript中with函数用法实例分析
2015/06/08 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
关于angularJs指令的Scope(作用域)介绍
2016/10/25 Javascript
原生JavaScript实现Tooltip浮动提示框特效
2017/03/07 Javascript
Angularjs的$http异步删除数据详解及实例
2017/07/27 Javascript
详解使用PM2管理nodejs进程
2017/10/24 NodeJs
antd Upload 文件上传的示例代码
2018/12/14 Javascript
微信小程序select下拉框实现源码
2019/11/08 Javascript
[56:35]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第二局
2016/02/27 DOTA
[01:01:14]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第一场 11.21
2020/11/23 DOTA
[01:11:21]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第三场 3月7日
2021/03/11 DOTA
Python对象与引用的介绍
2019/01/24 Python
python实现海螺图片的方法示例
2019/05/12 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
Python Selenium库的基本使用教程
2021/01/04 Python
CSS3实现翘边的阴影效果的代码示例
2016/06/13 HTML / CSS
英国拳击装备购物网站:RDX Sports
2018/01/23 全球购物
菲律宾最大的网上花店和礼品店:PhilFlower.com
2018/02/09 全球购物
Origins悦木之源香港官网:雅诗兰黛集团高端植物护肤品牌
2018/03/21 全球购物
Stokke美国官方网店:高级儿童家具、推车、汽车座椅和配件
2020/06/06 全球购物
地球一小时活动总结
2015/02/27 职场文书
JS不要再到处使用绝对等于运算符了
2021/04/30 Javascript
总结Python连接CS2000的详细步骤
2021/06/23 Python
浅谈克隆 JavaScript
2021/11/02 Javascript