[Python-3000] PEP: Eliminate __del__
Steven Bethard
steven.bethard at gmail.com
Fri May 4 20:02:45 CEST 2007
On 5/4/07, Guido van Rossum <guido at python.org> wrote:
> On 5/4/07, Raymond Hettinger <python at rcn.com> wrote:
> > An encapsulating function should be added to the weakref module
> > so that Guido's example could be written as:
> >
> > class BufferedWriter:
> >
> > def __init__(self, raw):
> > self.raw = raw
> > self.buffer = ""
> > weakref.cleanup(self, lambda s: s.raw.write(s.buffer))
>
> Or, instead of a new lambda, just use the unbound method:
>
> weakref.cleanup(self, self.__class__.flush)
>
> Important: use the dynamic class (self.__class___), not the static
> class (BufferedWriter). The distinction matters when BufferedWriter is
> subclassed and the subclass overrides flush().
>
> Hm, a thought just occurred to me. Why not arrange for object.__new__
> to call [the moral equivalent of] weakref.cleanup(self,
> self.__class__.__del__), and get rid of the direct call to __del__
> from the destructor? (And the special-casing of objects with __del__
> in the GC module, of course.)
That seems like a good idea, though I'm still a little unclear as to
how far the AttrMap should be going to look like a real instance. As
it stands, you can only access items from the instance __dict__. That
means no methods, class attributes, etc.::
>>> import weakref
>>> def cleanup(obj, callback, _reg=[]):
... class AttrMap(object):
... def __init__(self, map):
... self._map = map
... def __getattr__(self, key):
... return self._map[key]
... def wrapper(wr, mp=AttrMap(obj.__dict__), callback=callback):
... _reg.remove(wr)
... callback(mp)
... _reg.append(weakref.ref(obj, wrapper))
...
>>> class Object(object):
... # note that we do this in __init__ because in __new__, the
... # object has no references to it yet
... def __init__(self):
... super(Object, self).__init__()
... if hasattr(self.__class__, '__newdel__'):
... # note we use .im_func so that we can later pass
... # any object as the "self" parameter
... cleanup(self, self.__class__.__newdel__.im_func)
...
>>> class Foo(Object):
... def flush(self):
... print 'flushing'
... def __newdel__(self):
... print 'deleting'
... self.flush()
...
>>> f = Foo()
>>> del f
deleting
Exception exceptions.KeyError: 'flush' in <function wrapper at
0x00F34630> ignored
STeVe
--
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
--- Bucky Katt, Get Fuzzy
More information about the Python-3000
mailing list