R
Roy Smith
Roy Smith said: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.