__del__: when to use it? What happens when you SystemExit/NameError wrt del? Method vs function calls.

Veek. M vek.m1234 at gmail.com
Mon Mar 7 06:26:43 EST 2016


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.



More information about the Python-list mailing list