max*_*max 4 python garbage-collection destructor python-3.x
引用计数达到零后多久被__del__调用的方法?语言是否承诺在任何其他使用代码执行之前立即完成?或者每个实现可以做自己喜欢的事情,可能会将呼叫延迟到__del__任意长时间?
程序即将退出时请忽略这种情况(我认为这意味着给定块中的最后一个语句已经完成,并且堆栈为空).我明白在这种情况下,没有任何承诺__del__; 甚至根本不需要它.
此外,我知道由于周期等原因引用计数可能不为零.我在这里并不关心(我在问一个单独的问题).
Tho*_*ers 11
Python没有对何时__del__被调用或是否被调用做出任何保证.实际上,__del__如果对象是引用循环的一部分,则不太可能调用方法,因为即使整个循环被清理,Python也无法决定在哪里打破循环以及__del__方法的顺序(如果有的话)应该被召唤.由于__del__相当古怪的语义(为了调用__del__对象的引用计数暂时增加,并且该__del__方法可以通过在其他地方存储引用来防止对象的破坏)在其他实现中发生的事情有点像废话.(我不记得当前Jython中的确切细节,但它在过去已经改变了几次.)
也就是说,在CPython中,如果 __del__被调用,则只要引用计数降为零就会调用它(因为引用计数是__del__调用方法的唯一方法,CPython调用的唯一机会__del__是实际引用计数更改时).
关于你应该使用的唯一原因__del__是帮助垃圾收集器收集更多的垃圾.例如,如果您正在实现诸如ctypes将共享库附加到正在运行的进程的模块之类的东西,那么在收集对它的最后一个引用时卸载这些库是有意义的,以允许其地址空间用于其他内容.
为了管理其他类型的资源,您几乎肯定不希望与垃圾收集器有任何关系.对此的正确工具是上下文管理器.与C++或Ada等语言不同,其中变量作用域用于RAII,python使用该with语句以及具有__enter__和__exit__方法的对象.许多内置的python类型使用这种确切的机制来确保实际完成最终化步骤:
>>> x = file("foo", 'w')
>>> x.closed
False
>>> with x:
... x.write("bar")
...
>>> x.closed
True
Run Code Online (Sandbox Code Playgroud)
从蟒蛇的禅宗的角度来看,这也是有价值的:
显式优于隐式.
因为显然清理正在发生,所以它是以这种方式明确写出来的.当一些隐藏变量(引用计数,如果存在,并且它不在PyPy或IronPython或Jython中)达到某个特定值时,这比"清理"发生的情况要好得多.