On 10 Dec 2004 09:33:51 -0800, [EMAIL PROTECTED] wrote: >Bengt Richter wrote: >> On 9 Dec 2004 06:11:41 -0800, [EMAIL PROTECTED] (Egil M?ller) wrote: >> >> >So my naive implementation of a wrapper class, >> > >> > >> >class wrapper(object): >> > def __init__(self, value, otherdata): >> > self.value =3D value >> > self.otherdata =3D otherdata >> > def __getattribute__(self, name): >> > return getattr(self.value, name) >> > >> > >> >does not work. Any ideas for a solution? >> >> This seems to go some way towards it: >> [snip ugly wrapper hack] >> Not tested beyond what you see ;-) This doesn't wrap setting >attributes on the wrapped object, >> so setting attributes sets them on the wrapper itself, but that could >be fixed. >> >> Now what was it you wanted to use a wrapper for? ;-) [...] > > >Ah, thanks. I didn't think of the possibility of creating a list of >methods that needed wrapping, and wrapping them uppon creation of the >wrapper object. Mainly I think, becaus it seems to me as such an uggly >workaround for a misdesign in Python. Also, if the wrapped object gets It is ugly. I am not satisfied with it, but I wanted to offer some experimental results that might be useful (if only to decide not to go that way ;-) >some extra methods/callable member variables added "after the fact", >those will not get wrapped (this is however not a common thing to >happen, it just annoys me that it won't work). Well, that could be a feature, depending on what your use case is. Or you could make a method for adding methods, I suppose. A perfectly transparent wrap of obj would be to do nothing ;-) What do you actually want to do? > >However, I do have some questions about your implementation: > >If "if inst is None: return self" to protect for infinite recursion >when looking up self.__dict__? What self are you referring to? Anyway, inst is None when you access a descriptor instance as a class attribute, e.g., MyClass.desc as opposed to as an attribute of an instance of that class, e.g., MyClass().desc. Even __dict__ is actually itself a descriptor. Try type(obj).__dict__['__dict__'].__get__ (on a new style obj instance). vs type(obj).__dict__.__get__ which doesn't work.
> >What is the reason to give func to the MethodDesc property object, why >does its __get__ method have to do > >if func: return func.__get__(self.thing, type(self.thing)) > >? This is to create a bound method that's bound to the thing, not to the wrapper object. I guess this could be done at wrapping time instead. I was just hacking down the path of least resistance ;-) > >What is the reason to neither wrap, nor just copy, any of __getattr__, >__getattribute__, __setattr__, '__new__' or '__init__'? Especially >__getattr__, __getattribute__ and __setattr__ seems to need at least >some type of wrapping (but perheaps some special one)? Sorry, this was to eliminate some problems I had along the way. But __new__ and __init__ have to be kept out of the Wrapper class or they will be invoked when Wrapper() is done to create the wrapped object. I have hacked something better, not using def __metaclass__, which isn't necessary. (I just prepare a cdict similarly, and then use that in Wrapper = type('Wrapped_'+type(thing).__name__, (object,), cdict) plus playing games to avoid the wrong __init__ and __new__ etc.) Also, I just remembered an idea that someone had used to limit methods in an attempt at security by assigning obj.__class__ with a compatible class. So that might be an avenue too. Maybe a wrapper could be a subclass of type(obj), and then just copy method function references to the wrapper class dict? I'll have to explore that another time... What is your actual use case? ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list