对象析构函数__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的Flask框架中实现单元测试的教程
Apr 20 Python
python操作redis方法总结
Jun 06 Python
python日志logging模块使用方法分析
May 23 Python
Python 中的 global 标识对变量作用域的影响
Aug 12 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
Aug 27 Python
python对常见数据类型的遍历解析
Aug 27 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
Jul 14 Python
python中_del_还原数据的方法
Dec 09 Python
全网最细 Python 格式化输出用法讲解(推荐)
Jan 18 Python
python设置 matplotlib 正确显示中文的四种方式
May 10 Python
利用Pycharm连接服务器的全过程记录
Jul 01 Python
基于Python实现一个春节倒计时脚本
Jan 22 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
php将csv文件导入到mysql数据库的方法
2014/12/24 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
详细介绍8款超实用JavaScript框架
2013/10/25 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
浅析IE10兼容性问题(frameset的cols属性)
2014/01/03 Javascript
jquery解析xml字符串简单示例
2014/04/11 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
详解JavaScript中Date.UTC()方法的使用
2015/06/12 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
JS组件Bootstrap Select2使用方法详解
2020/04/17 Javascript
JavaScript中获取纯正的undefined的方法
2016/03/06 Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
2016/07/05 Javascript
前端js实现文件的断点续传 后端PHP文件接收
2016/10/14 Javascript
bootstrap使用validate实现简单校验功能
2016/12/02 Javascript
jQuery简易时光轴实现方法示例
2017/03/13 Javascript
jquery ui sortable拖拽后保存位置
2017/04/27 jQuery
vue使用better-scroll实现下拉刷新、上拉加载
2018/11/23 Javascript
JavaScript函数式编程(Functional Programming)纯函数用法分析
2019/05/22 Javascript
jQuery 选择器用法基础入门示例
2020/01/04 jQuery
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
解决Vue-cli无法编译es6的问题
2020/10/30 Javascript
python使用MySQLdb访问mysql数据库的方法
2015/08/03 Python
详解python中字典的循环遍历的两种方式
2017/02/07 Python
kafka-python批量发送数据的实例
2018/12/27 Python
python tkinter之顶层菜单、弹出菜单实例
2020/03/04 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
python如何实现图片压缩
2020/09/11 Python
canvas探照灯效果的示例代码
2018/11/30 HTML / CSS
阿迪达斯意大利在线商店:adidas意大利
2016/09/19 全球购物
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
高校教师思想汇报
2014/01/11 职场文书
公司总经理助理岗位职责
2014/07/09 职场文书
教师工作态度自我评价
2015/03/05 职场文书
交通安全宣传标语(100条)
2019/08/22 职场文书
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android
Python 多线程处理任务实例
2021/11/07 Python