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?
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
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. */
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
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With