does python have useless destructors?

Roy Smith roy at panix.com
Fri Jun 11 17:57:39 EDT 2004


In article <e251b7ba.0406111238.4de7458d at posting.google.com>,
 dkturner at telkomsa.net (David Turner) wrote:

> Roy Smith <roy at panix.com> wrote in message 
> news:<roy-235923.08060411062004 at reader2.panix.com>...
> > dkturner at telkomsa.net (David Turner) wrote:
> > > 1. Objects of classes that declare a __del__ method shall be referred
> > > to as "deterministic" objects.  Such objects shall have a reference
> > > count associated with.  The reference count shall be incremented
> > > atomically each time an additional reference to the object is created.
> > >  The reference count shall be decremented each time a name referring
> > > to the object is deleted explicitly.  Except in the situation
> > > described in (2) below, the reference count shall be decremented each
> > > time a name referring to the object becomes inaccessible due to the
> > > set of locals to which the name belongs becoming inaccessible.
> > > [...]
> > > 3. When the reference count of a deterministic object reaches zero,
> > > the __del__ method of the object shall be called.
> > 
> > What if you do this...
> > 
> > class Top:
> >    def __init__ (self):
> >       self.bottom = Bottom ()
> > 
> > class Bottom:
> >    def __del__ (self):
> >       do something really important
> > 
> > top = Top ()
> > del top
> > 
> > The problem here is that while Bottom.__del__ will get called as soon at 
> > top releases it's reference, there's nothing to guarantee that the 
> > reference will disappear until top is garbage collected.  You could fix 
> > that by writing Top.__del__, but that assumes Top is a class you have 
> > control of (it might be something out of a library).
> > 
> > Or am I not understanding the situation right?
> 
> This particular example you cite is not actually problematic.  The
> point is that the resources are cleaned up when Top is cleaned up,
> which is what we want.  How and when Top is cleaned is neither here
> nor there.

Well, ok, let's change it a little.  Let's do:

# Top is unchanged from earlier example ...
class Top:
   def __init__ (self):
      self.bottom = Bottom ()

# .... but Bottom is a little different ...
class Bottom:
   def __init__ (self):
      self.exclusiveAccessResource = getResource ()

   def __del__ (self):
      del self.exclusiveAccessResource

# ... and the calling sequence changes too
top = Top ()
del top
top = Top ()

Now, I've designed Top to be a sort of bastard cousin (or maybe an evil 
twin?) of a singleton.  Instead of getting the same one each time, you 
get a new one but you're only allowed to create one of them at a time.  
The exclusiveAccessResource might be something like a mutex, or it might 
be something external like a low-numbered network port.  If the "del 
Top" doesn't actually free the resource, the second call to Top() will 
fail.



More information about the Python-list mailing list