__del__
的python文档解释了当引用计数减少到零时,可以调用对象的__del__
方法。是否总是立即调用(即同步)?或者有可能在将来某个时候调用__del__
方法吗?
此外,这个问题的答案一般适用于Python吗?或者是否为语言实现提供了一些自由度? (我使用CPython。)
对于这个问题,假设如下:
object
。__del__
实施。__del__
实现不会创建对任何对象的新引用。据我所知,这个话题似乎有很多混乱。为了避免不必要的讨论,我们举一些不可接受的答案:
__del__
!这令人困惑!”__del__
!这不是'pythonic'。”__del__
,而是使用上下文管理器。”要使用示例重新解释此问题,请考虑以下代码:
class C(object):
def __init__(self, i):
self.i = i
def __del__(self):
print "C.__del__:", self.i
print "Creating list"
l = [C(0), C(1), C(2)]
print "Popping item 1"
l.pop(1)
print "Clearing list"
l = []
print "Exiting..."
产生以下输出:
$ python test_del.py
Creating list
Popping item 1
C.__del__: 1
Clearing list
C.__del__: 2
C.__del__: 0
Exiting...
请注意,在此示例中,同步调用__del__
。这种行为是否由语言保证? (请记住上面列出的假设。)
答案 0 :(得分:3)
来自Python语言参考(Python 2.7.3版),Chapter 3, Data model:
永远不会明确销毁对象;然而,当它们变得无法到达时,它们可能被垃圾收集。允许实现推迟垃圾收集或完全省略它 - 实现垃圾收集的实现质量问题,只要没有收集到仍然可以访问的对象。
CPython实现细节:CPython目前使用引用计数方案和(可选)延迟检测循环链接垃圾,一旦它们无法访问就收集大多数对象,但不保证收集包含循环引用的垃圾。有关控制循环垃圾收集的信息,请参阅
gc
模块的文档。其他实现的行为不同,CPython可能会改变。当对象无法访问时,不要依赖于对象的立即终结(例如:总是关闭文件)。
答案 1 :(得分:1)
语言无法保证此行为。例如,请参阅PyPy's documentation on their garbage collection scheme,其中明确指出在PyPy中调用__del__
的时间与CPython不同。
如果你的对象不是引用周期的一部分,那么我理解这种行为在CPython中是可靠的,但我不知道任何明确的保证。