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.:: >>> 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 _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com