我认为这是访谈中最常见的问题:
class A:
def __init__(self, name):
self.name = name
def __del__(self):
print self.name,
aa = [A(str(i)) for i in range(3)]
for a in aa:
del a
这个代码的输出是什么以及为什么。 输出将是什么,为什么? 那是因为a是对列表中的对象的引用然后我们调用del方法我们删除这个引用而不是对象吗?
答案 0 :(得分:5)
至少有2个引用a
引用的对象(变量是引用到对象,它们本身不是对象)。列表中有一个引用,然后是引用“a
”。当您del a
时,删除一个引用(变量a
),但不删除列表中的引用。
另请注意,Python不保证将__del__
被调用...
答案 1 :(得分:4)
__del__
;这将在从程序的可访问内存中删除对象的最后一个可能引用之后发生。根据实施情况,这可能会立即发生,也可能会在一段时间后发生。
您的代码只是从执行范围中删除了本地名称a
;对象仍保留在列表中,因此仍可访问。例如,尝试编写del aa[0]
。
答案 2 :(得分:3)
来自文档:
当垃圾收集器找到要销毁的对象时,会触发注意del x不直接调用
x.__del__()
- 前者将x的引用计数递减1,而后者仅在x的引用计数达到零时调用。
__del__
。垃圾收集器将尝试销毁引用计数为0的对象。del
只是解耦本地命名空间中的标签,从而减少解释器中对象的引用计数。垃圾收集器的行为在很大程度上被认为是解释器的实现细节,因此无法保证对象的__del__
将以任何特定顺序调用,甚至根本不会。这就是为什么这段代码的行为是未定义的。