为什么第一次迭代中的对象在第二次迭代中被删除?

Why is object from first iteration deleted on second iteration?

给定以下代码:

class wat():
    def __init__(self):
        self.ok = "ok"
        print "hi"

    def __del__(self):
        print "bye"

i = [1,2,3,4]

for thing in i:
    print thing
    hey = wat()

我得到以下输出:

1
hi
2
hi
bye
3
hi
bye
4
hi
bye
bye

看起来在一次迭代中创建的对象直到 下一次迭代中的对象被创建后才会被销毁。这是实际发生的事情吗?如果是,为什么要这样做?我一直假设一旦迭代完成,所有变量和对象都会消失(除非有其他东西引用这些对象)。

这是正常的。每次您 运行 通过 hey = wat() 行时,都会创建一个新对象(您会得到 'hi'),然后它会替换 hey 中的旧对象。旧的然后被销毁,因为没有任何东西指向它。 (请注意,如 Assignment Statements 的 Python 文档中所述,首先计算右侧表达式,然后才将结果绑定到左侧的变量(因此,您首先得到一个hi 来自 wat() 的执行,然后才 bye.

显然,在第一次迭代中,hey 未定义,因此在 1 行之后只有 hi

未引用的旧对象在创建新对象后被垃圾回收,因为只有在当前命名空间中重新使用引用hey后,旧对象才不再被引用。这会在每个循环中自动发生。

正如其他社区成员已经解释的那样,hey 是对您当前 wat 实例的唯一引用,一旦您重新分配该引用,之前引用的对象将被垃圾回收。

此处对您的代码进行了细微修改,以抑制垃圾回收。除了教育之外,它并没有什么用。

class wat():
    eternal_storage = []

    def __init__(self):
        self.ok = "ok"
        print "hi"
        self.eternal_storage.append(self)

    def __del__(self):
        print "bye"

i = [1,2,3,4]

for thing in i:
    print thing
    hey = wat()

输出:

1

2

3

4

由于 wat.eternal_storage 持有所有曾经创建的 wat 对象,重新分配引用 hey 不会删除对任何 wat 对象和 wat.__del__ 的最后引用不会被调用。