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

Yuu*_*shi 2 python garbage-collection

在测试一个包含弱引用的类时,我偶然发现了这个有点奇怪的行为: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 = []
Run Code Online (Sandbox Code Playgroud)

以上将打印:

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)
Run Code Online (Sandbox Code Playgroud)

此外,尝试创建一个大型列表(再次)强制垃圾收集什么都不做; 例如,在插入之间的以下x = []gc.collect(2)以上:

p = [i for i in range(10000000)]
Run Code Online (Sandbox Code Playgroud)

这在Python 2.7.6和3.3.3上都会发生.我意识到垃圾收集是非确定性的,但这似乎相当可疑.是否有一个特定的原因,最后一个元素不是垃圾收集,还是这是一种一个一个一个错误?

Seb*_*ler 5

t一个源代码中的变量仍然存在,并保存对最后一个条目的引用.调用后del t,最后一个TestObject将被删除.