Calling 'del' on a list

假如想象 提交于 2019-12-07 04:27:53

问题


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

This prints 2, 1, 0.


  • Now, is the order of the deleted elements defined somewhere in specification or is it implementation-specific? (or maybe I don't understand the underlying mechanics)

  • Could the output, for example, be 0, 1, 2? I realize the 2, 1, 0 order is probably done to avoid the memory reallocations for the elements while deleting them, but still the question remains.

  • And the last one - what's the difference between del l and del l[:] statements?


回答1:


Running del l will remove any reference to the list, so the symbol l will be gone. In contrast, running del l[:] removes the contents of the list, leaving l as an empty list.

The __del__ method is what runs when the last reference to an instance is being destroyed.

The order of deletion isn't specified and is implementation specific. When you run del l, the only thing that is guaranteed is that the reference count for the list l and each of its elements will decrease by one.

With pypy, nothing else will happen until the garbage collector is run. The order of the object removal depends on the order that GC visits the objects.

In cpython, the OP was correct in observing that reference decrementing occurs right-to-left. When invoking del l[:] here is the code used to decrement the refcounts: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700 . When del l is invoked, similar code is used to decrement the refcounts: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596




回答2:


Others have already answered. I'll just add what I found in CPython sources.

The list_dealloc function in listobject.c file contains this comment immediately before looping over list items to decrement their reference counts:

    /* 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. */



回答3:


  • Deletion order is implementation-specific.
  • Per the answer to the first point, yes it could delete it in some other order (even elements first, random, whatever), and avoiding reallocations has little to do with it. It's just a matter of how the implementation chooses to walk the children. Perhaps the memory allocator is happier if the order of freeing reverses the order of allocating; but that's just a guess.
  • del l deletes the variable itself (and thus the list, if nothing else holds it), whereas del l[:] removes all the elements from the list. Try del l; print l.


来源:https://stackoverflow.com/questions/8205102/calling-del-on-a-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!