在列表上调用'del'

时间:2011-11-20 22:02:23

标签: python list del

class ToBeDeleted:
    def __init__(self, value):
        self.value = val

    # Whatever...

    def __del__(self):
        print self.value

l = [ToBeDeleted(i) for i in range(3)]
del l

这会打印2, 1, 0


  • 现在,已删除元素的顺序是在规范中定义的,还是特定于实现的? (或者我可能不理解底层的机制)

  • 例如,输出可能是0, 1, 2吗? 我意识到2, 1, 0顺序可能是为了避免在删除元素时重新分配元素,但问题仍然存在。

  • 最后一项 - del ldel l[:]陈述之间的区别是什么?

3 个答案:

答案 0 :(得分:8)

运行del l将删除对列表的任何引用,因此符号 l 将消失。相反,运行del l[:]会删除列表中的内容,将 l 保留为空列表。

__del__方法是在销毁实例的最后一个引用时运行的方法。

未指定删除顺序,并且是特定于实现的。当您运行del l时,唯一可以保证的是列表 l 的引用计数及其每个元素将减少一个。

使用 pypy ,在运行垃圾收集器之前不会发生任何其他事情。对象删除的顺序取决于GC访问对象的顺序。

cpython 中,OP在观察到从右到左发生参考递减时是正确的。在此处调用del l[:]时,用于递减refcounts的代码为:http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700。调用del l时,类似的代码用于递减引用:http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596

答案 1 :(得分:2)

其他人已经回答了。我将添加我在CPython源代码中找到的内容。

list_dealloc文件中的listobject.c函数在循环列表项之前立即包含此注释,以减少其引用计数:

    /* Do it backwards, for Christian Tismer.
       There's a simple test case where somehow this reduces
       thrashing when a *very* large list is created and
       immediately deleted. */

答案 2 :(得分:1)

  • 删除顺序是特定于实现的。
  • 根据第一点的答案,是的,它可以以其他顺序删除它(甚至首先是元素,随机,等等),避免重新分配与它几乎没有关系。这只是实施选择如何让孩子们走路的问题。如果释放顺序颠倒了分配顺序,则内存分配器可能会更快乐;但这只是猜测。
  • del l删除变量本身(因此列表,如果没有别的东西保留它),而del l[:]删除列表中的所有元素。试试del l; print l