Reputation: 1178
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?
Upvotes: 1
Views: 2617
Reputation: 1121584
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.
Upvotes: 8