Michele Simionato wrote: > On Aug 10, 7:09 pm, Steven Bethard <[EMAIL PROTECTED]> wrote: >> There were also a few recipes posted during this discussion that wrap >> weakrefs up a bit nicer so it's easier to use them in place of __del__: >> >> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/519635 > > I knew about your recipe and I thought it was clever, *very* > clever. I have been thinking about it a bit more today and > here is an alternative, which does not require metaclasses, > does not require descriptors, and does not require the user to > declare the attributes she will use in the __finalize__ method. > Warning: it is no more tested than the test case in your recipe: > > import weakref > > _get = object.__getattribute__ > _set = object.__setattr__ > _del = object.__delattr__ > > def getinnerobj(self): > return _get(self, '*innerobj*') > > class Impostor(object): > "It tries very hard to impersonate the inner object" > def __init__(self, obj): > _set(self, '*innerobj*', obj) > def __getattribute__(self, name): > return getattr(getinnerobj(self), name) > def __setattr__(self, name, value): > _set(getinnerobj(self), name, value) > def __delattr__(self, name): > _del(getinnerobj(self), name) > > _refset = set() > > class Finalized(object): > def __new__(cls, *args, **kw): > self = super(Finalized, cls).__new__(cls, *args, **kw) > self.__init__(*args, **kw) > def finalize(ref, refset=_refset): > refset.remove(ref) > cls.__finalize__(self) > fake = Impostor(self) > _refset.add(weakref.ref(fake, finalize)) > return fake > def __finalize__(self): > pass
The problem here is that __getattribute__ doesn't work for things like __getitem__. So the fake object can't properly delegate these:: >>> class C(Finalized): ... def __getitem__(self, key): ... return key ... >>> c = C() >>> c[1] Traceback (most recent call last): File "<interactive input>", line 1, in <module> TypeError: 'Impostor' object is unindexable AFAIK, with new-style classes, there is no way to do this kind of delegation properly. STeVe -- http://mail.python.org/mailman/listinfo/python-list