垃圾收集器缺少列表中的最后一个值 - python

在测试包含弱引用的类时,我偶然发现了这种有点奇怪的行为:Python垃圾收集器似乎缺少列表中的最后一个元素。一个最小的例子:

class Test(object):

    def __init__(self, i):
        self.i = i

    def __del__(self):
        print('Deleting Test {0}'.format(self.i))

if __name__ == '__main__':

    x = [Test(i) for i in range(5)]
    for t in x:
        print(t.i)
    x = []

上面将打印:

0

1个

2

3

4

删除测试3

删除测试2

删除测试1

删除测试0

无论创建的对象列表的大小如何(10、100、1000等),都会发生这种情况。为了再次检查是否存在这种情况,我尝试强制进行垃圾回收,并确保在将原始列表设置为[]后仍可以使用对原始列表值的弱引用(并且未将其标记为无效)。或致电del x:

import weakref
import gc

z = None

if __name__ == '__main__':
    x = [Test(i) for i in range(5)]
    for t in x:
        print(t.i)

    z = weakref.ref(x[4])
    x = []
    gc.collect(2)
    print(z().i)

此外,尝试创建一个较大的列表来(再次)强制垃圾回收并没有任何作用。例如,在上面的x = []gc.collect(2)之间插入以下内容:

p = [i for i in range(10000000)]

这在Python 2.7.6和3.3.3上都发生。我意识到垃圾回收是不确定的,但这似乎很可疑。是否有一个特定的原因导致最后一个元素没有被垃圾回收,或者这是一种“一站式”错误?

python大神给出的解决方案

您的第一个源代码中的变量t仍然存在,并保留对最后一个条目的引用。调用del t后,最后一个Test对象将被删除。