Steven D'Aprano wrote:
> On Monday 07 March 2016 17:13, Veek. M wrote: > >> import foo >> class Bar(object): >> def __del__(self, foo=foo): >> foo.bar() # Use something in module foo >> >> ### Why the foo=foo? import foo, would increment the ref-count for >> object 'foo' > > Yes. And then at shutdown, the module globals get deleted so it gets > decremented again and then garbage collected. > > You cannot tell what order objects will be deleted, so you cannot tell > whether your instance will be deleted before or after foo. If it > happens before foo, then __del__ will run and you will be fine. If it > happens after foo, then foo is gone and your __del__ method will fail. > > >> so why go to all the effort of passing it in to every >> instance via the local stack (ref-to-object-foo)? > > So that every instance has a guaranteed and reliable reference to foo > that cannot be garbage collected before that instance. > > Here is a sketch of what happens without the foo=foo: > > import foo # refcount = 1 > x = Bar() # make an instance > y = Bar() # and another instance > ... > z = Bar() # another instance > ... > ... > del z # z gets garbage collected, everything is fine > ... > sys.exit() # Shutdown starts, x and y still exist > # Python starts garbage collecting objects > # in some unknown order... > ... > ... > del x # x gets garbage collected, foo still exists so everything is > fine > del foo # refcount = 0, so foo gets garbage collected > del y # y gets garbage collected, but foo is gone! > > > > > Here is a sketch of what happens with the foo=foo: > > import foo # refcount = 1 > x = Bar() # make an instance, foo refcount = 2 > y = Bar() # and another instance, foo refcount = 3 > ... > z = Bar() # another instance, foo refcount = 4 > ... > ... > del z # z gets garbage collected, foo refcount = 3 > ... > sys.exit() # Shutdown starts, x and y still exist > # Python starts garbage collecting objects > # in some unknown order... > ... > ... > del x # x gets garbage collected, foo refcount = 2 > del y # y gets garbage collected, foo refcount = 1 > del foo # refcount = 0, so foo gets garbage collected > > > > This guarantees that so long as there are any instances yet to be > garbage collected, foo cannot be be garbage collected. Only after the > last of those instances are gone will foo be garbage collected. > > > >> Text for 1,2 from Beazley: >> It’s important to note that in some cases the __del__() method might >> not be invoked at program termination.This can occur if circular >> references exist between objects (in which case objects may be >> allocated but accessible from no known name-space).Although Python’s >> garbage collector can reclaim unused circular references dur-ing >> execution, it isn’t normally invoked on program termination. >> >> ### which begs the question, why not on program termination? > > I'm afraid I don't know. Perhaps read the source code? > > >> How bad can >> it be since you are terminating anyway. __del__ seems like a total >> waste product method > > I won't say "total" waste product, but automatic destructor methods > are only good for very simple use-cases where you don't care that they > are called in a non-deterministic fashion. > > > Hi thanks! I kind of posted and your reply came through. Got it. -- https://mail.python.org/mailman/listinfo/python-list