Search code examples
pythonlistdel

Calling 'del' on a list


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?


Solution

  • 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