[Python-ideas] breaking cycles that include __del__
Scott Dial
scott+python-ideas at scottdial.com
Mon Oct 19 22:46:43 CEST 2009
Daniel Stutzbach wrote:
> Unfortunately, if the object ends up in a cycle, then the recipe can't
> do its job because __del__ will never be called.
The way I have always dealt with these problems is to not have
overly-generalized objects. If I have a resource to acquire that needs
to have a __del__ to clean-up after itself (as you suggest, in case a
close() was not called), then that is *all* that object does. The only
way you can get trapped into a cycle is if you design a
resource-managing object that holds references to other objects, which
was bad design.
I don't see the need for a recipe like the one Nick linked to. Everyone
can agree it is ugly, I think. But, the real goal was to split out the
core of the object required for clean-up. So, I am saying, actually
split it out! Classes are cheap.
class _CoreWidget:
def __init__(self, *args, **kwds):
self.closed = False
# Acquire resources
def close(self):
if self.closed:
return
self.closed = True
# Free resources
def __del__(self):
if not self.closed:
print('%s not closed properly' % repr(self))
self.close()
class Widget:
def __init__(self, *args, **kwds):
self._core_widget = _CoreWidget(*args, **kwds)
x, y = Widget(), Widget()
x.y, y.x = y, x
del x; del y
# <__main__._CoreWidget instance at 0x00B3F418> not closed properly
# <__main__._CoreWidget instance at 0x00B3E328> not closed properly
--
Scott Dial
scott at scottdial.com
scodial at cs.indiana.edu
More information about the Python-ideas
mailing list