del调用了一个没有完成init的对象吗?

Mat*_*ner 20 python python-3.x

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

Lau*_*low 24

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

    def __del__(self):
        print "__del__ called"

try:
    test()
except:
    pass
Run Code Online (Sandbox Code Playgroud)

是.

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

当然,__del__如果程序即将退出,则无法保证成功运行,除非小心,并且在某些情况下甚至不会 - 请参阅__del__警告.

Addenum: CédrikJulien在他的回答(现在修正)中说:" 如果__new__引发异常,你的对象将不会被创建,__del__也不会被调用 ".这并不总是正确的.这是一个__del__调用的例子,即使引发了异常__new__:

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

    def __del__(self):
        print "__del__ called"
Run Code Online (Sandbox Code Playgroud)

因此,在返回之前我们对test对象做了一些事情时发生了一些异常obj.但是由于对象已经创建,因此__del__被调用.教训是:__del__方法中,不要假设object.__new__()事实上发生之后应该发生的任何事情.否则,您可能会尝试访问不存在的属性或依赖其他一些无效的假设引发异常.该异常将被忽略,但任何__del__应该完成的任务也将失败.


Céd*_*ien 14

答案是肯定的.

正如这里 所讨论__del__的不是相反__init__,而只是相反的__new__.

如果__new__在创建对象之前引发异常(通常在超类调用之前),则不会创建对象,__del__也不会调用该对象,否则__del__将创建对象并将其进行调用.

__init__方法是一个后期初始化器,真正的对象构造函数是__new__()方法.