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.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to