如果一个对象的__init__没有完成(比如抛出异常),会调用__del__吗?

推荐答案

class test():
    def __init__(self):
        raise

    def __del__(self):
        print "__del__ called"

try:
    test()
except:
    pass

当删除对对象的最后一个引用时,将调用Explanation: __del__.但是如果没有捕获异常,将不会调用__del__,因为python仍然在堆栈中保留对该对象的引用,并且会一直保留到程序退出以打印回溯.如果捕获并处理异常,那么一旦从堆栈中丢弃与异常相关的所有信息,对象就会被删除.

当然,如果程序即将退出,__del__也不一定能成功运行,除非谨慎行事,在某些情况下甚至不能成功运行——参见__del__ warning.

Addenum:塞德里克·朱利安(Cédrik Julien)在他的回答(现已修订)中说:"If 100 raised an exception, your object won't be created and 101 won't be called".这并不总是正确的.下面是一个调用__del__的示例,尽管在__new__中引发了异常:

class test():
    def __new__(cls):
        obj = object.__new__(cls)
        raise
        return obj

    def __del__(self):
        print "__del__ called"

因此,在返回之前,我们对test对象obj做了一些操作,出现了一些异常.但由于对象已经创建,因此调用__del__.教训是:in the 102 method, don't assume anything that was supposed to happen after 104 has in fact happened.否则,您可能会在try 访问不存在的属性时引发异常,或者依赖于其他无效的假设.例外情况将被忽略,但__del__本应完成的任何任务也将失败.

Python-3.x相关问答推荐

DuckDB:带有嵌套对象的星形表达式

Python将类实例变量转换为嵌套 struct

十进制浮点数到整型的转换错误

无法使用xpath关闭selenium中的弹出窗口

无法导入名称';核心';来自部分初始化的模块';tensorflow_datasets';(很可能是由于循环导入)

将两列的乘积连续添加到一列的累积和中

如何立即从asyncio.Task获取异常?

Pandas教程:如何更新行内数值的位置

Python:如何从句子/段落中提取地址(非正则表达式方法)?

使用 pandas 进行多类分类的总体准确度

类型提示和链式赋值以及多重赋值

Pytorch 的随机 Select ?

基本 Flask 应用程序未运行(TypeError:模块中缺少必填字段type_ignores)

Python 3:函数参数中的省略号?

为什么在 Python 中不推荐使用 MutableString?

如何在 jupyter notebook 5 中逐行分析 python 3.5 代码

如何为 Python 3.x 安装 psycopg2?

Django Rest 框架 ListField 和 DictField

字典理解中的操作顺序

如何从Pandas 中的字符串中提取前8个字符