Wrapper objects

Bengt Richter bokr at oz.net
Fri Dec 10 14:43:16 EST 2004


On 10 Dec 2004 09:33:51 -0800, redhog at takeit.se wrote:

>Bengt Richter wrote:
>> On 9 Dec 2004 06:11:41 -0800, redhog at takeit.se (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



More information about the Python-list mailing list