__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