On 5/4/07, Steven Bethard <[EMAIL PROTECTED]> wrote: > On 5/4/07, Guido van Rossum <[EMAIL PROTECTED]> wrote: > > On 5/4/07, Raymond Hettinger <[EMAIL PROTECTED]> 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.::
Oh, you mean 'self' as passed to the callback is not the instance? That kills the whole idea (since the typical __del__ calls self.flush() or self.close()). > >>> 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 If it really has to be done this way, I think the whole PEP is doomed. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-3000 mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com
