Python 为什么';工作正常

Python 为什么';工作正常,python,class,Python,Class,我认为这是面试中最常见的问题: 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 这段代码的输出是什么,为什么。 输出将是空的,为什么? 这是因为列表中的对象上有一个引用,然后我们调用del方法

我认为这是面试中最常见的问题:

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
这段代码的输出是什么,为什么。 输出将是空的,为什么?
这是因为列表中的对象上有一个引用,然后我们调用del方法。我们删除这个引用,但不删除对象?

至少有两个引用
a
引用的对象(变量是对对象的引用,它们不是对象本身)。列表中有一个引用,然后是引用“
a
”。
dela
时,删除一个引用(变量
a
),但不删除列表中的引用


还要注意的是,Python并不保证在对象被销毁时调用
\uuuu del\uuu

\uu del\uuu
;这将在从程序的可访问内存中删除对对象的最后一个可能引用后发生。根据实现情况,这可能会立即发生,也可能会在一段时间后发生

您的代码只是将本地名称
a
从执行范围中删除;该对象仍保留在列表中,因此仍然可以访问。例如,尝试编写del aa[0]。

从文档:

注意del x不直接调用
x.\uu del\uuu()
-前者将x的引用计数递减1,后者仅在x的引用计数达到零时调用


垃圾收集器发现要销毁的对象时会触发
\uu del\uu
。垃圾收集器将尝试销毁引用计数为0的对象
del
只是将本地名称空间中的标签解耦,从而减少解释器中对象的引用计数。垃圾收集器的行为在很大程度上被视为解释器的一个实现细节,因此不能保证对象上的
\uuu del\uu
将以任何特定顺序调用,甚至根本不能。这就是为什么这个代码的行为是未定义的。

它对
dela
来说不是多余的吗?在循环的下一次迭代中,对象
a
标签的引用计数是否会减少?关于最后一点达成一致:作为独立程序运行OP的代码最终会在CPython 2.7.3下产生“2 1 0”,但在PyPy 1.9.1或Jython 2.5.1下不会产生输出,因为从来没有调用过
\uuu del\uuu
。@sr2222大概是的(除了列表中的最后一个元素)@DSM--是的,我知道你在说什么并删除了我的评论:)。感谢你提供了这个具体的例子。谁会让你在面试中描述一段模糊的、无用的代码,其行为根据语言规范本身是不确定的或未定义的?这些C或Java程序员是想面试Python的职位吗?哈哈,我大概问了3到4次这个问题。)