5
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 l最后一个 -和del l[:]语句有什么区别?

4

3 回答 3

8

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

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

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

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

cpython中,OP 在观察到引用递减从右到左发生时是正确的。在这里调用时del l[:]是用于减少引用计数的代码: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

于 2011-11-20T22:04:43.860 回答
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. */
于 2011-11-20T22:21:26.163 回答
1
  • 删除顺序是特定于实现的。
  • 根据对第一点的回答,是的,它可以按其他顺序删除它(甚至是元素优先,随机等等),并且避免重新分配与它无关。这只是实施选择如何步行孩子的问题。如果释放的顺序与分配的顺序相反,那么内存分配器可能会更快乐;但这只是一个猜测。
  • del l删除变量本身(因此列表,如果没有其他东西保存它),同时del l[:]从列表中删除所有元素。试试del l; print l
于 2011-11-20T22:11:00.610 回答