Python objects are not deleted

2.5k Views Asked by At

I have the next code (here I try to catch the last object existing):

class Mogican(object):
    last = None

    def __init__(self, name):
        # print("Created")
        self.name = name
        self.prev = None
        self.next = None
        if self.__class__.last == None:
            self.__class__.last = self
            self.prev = None
            self.next = None
        else:
            self.prev = self.__class__.last
            self.__class__.last.next = self
            self.__class__.last = self
            self.next = None

    def __del__(self):
        print("Deleted")
        if self.next == None:
            print("here")
            self.__class__.last = self.prev
            self.prev.next = None
        else:
            print("no here")
            self.prev.next = self.next

            self.next.prev = self.prev

And my main file main.py:

from Mogican import Mogican

if __name__ == '__main__':
    m1 = Mogican('adin')
    m2 = Mogican('dva')
    m3 = Mogican('tree')
    m4 = Mogican('Cheture')

    # print Mogican.last.name

    print m4
    del m4

But when I delete m4, no print is called but the object is deleted. And can't find why no print is displayed from the __del__ method?

1

There are 1 best solutions below

0
On BEST ANSWER

Python only deletes objects from memory (and calls their __del__ hook if there is any) when there are no references left to the object.

m4 is referenced by m3, which in turn is referenced by m2, etc. So not until all four objects are deleted would Python be able to free any of these objects.

You still won't see __del__ being called if you are using Python 3.3 or before; as you created circular references here even the garbage collector won't free these as your objects have __del__ hooks. See the gc.garbage documentation:

Objects that have __del__() methods and are part of a reference cycle cause the entire reference cycle to be uncollectable, including objects not necessarily in the cycle but reachable only from it. Python doesn’t collect such cycles automatically because, in general, it isn’t possible for Python to guess a safe order in which to run the __del__() methods.

Python 3.4 implements PEP 442, removing this limitation.

You should use weak references if you don't want certain references to count against an object lifetime or to be seen as circular references.

You could use a weakref.WeakSet() object the class level, adding your instances to that. If that set is empty when __del__ is called, your last instance was deleted.