subclassing extension type and assignment to __class__

Gregory Lielens gregory.lielens at fft.be
Thu Dec 2 05:45:15 EST 2004


> Unless I'm misunderstanding, couldn't one of __getattr__ or
> __getattribute__ make mapping other methods you don't override very
> simple and practical, not to mention fully automated with 2-3 lines of
> code?  In particular, __getattr__ would seem good for your use since
> it is only called for attributes that couldn't already be located.
> 
> I've had code that wrapped underlying objects in a number of cases, and
> always found that to be a pretty robust mechanism.

Thanks for mentioning this, after more research I came up with something
usable, using delegating technique from python cookbook:


#wrapper
 
def wrap_class(base):
    class wrapper:
        __base__=base
        def __init__(self,*args,**kwargs):
            if len(args)==1 and type(args[0])==self.__base__ and kwargs=={}:
                self._base = args[0]
            else:
                self._base=self.__class__.__base__.__new__(self.__class__.__base__,*args,**kwargs)
        def __getattr__(self,s):
            return self._base.__getattribute__(s)
    return wrapper
     
 
 
#wrap class
complex2=wrap_class(complex)
#extend wrapper class
def supaprint(self):
    print "printed with supaprint(tm):"
    print self
complex2.supaprint=supaprint
 
#define wrapper class from base class
c1=1+1j
c2=complex2(c1)
#test old functionalities
print c1==c2
print "c1=",c1
print "c2=",c1
#test extension
c2.supaprint()
c1.supaprint()

So this basically fit the bill, it even delegates special methods it
seems, although I am not sure why...It is like writting heritage ourself,
in a way :-)

Remaning problem is that if we use the class generating
wrapper function (simple), we loose the classic class definition syntax
and rely on explicitely adding methods.
The alternative is to include the wrapper
machinery in every "home-derived" class, but you are right, it is not as bad as I
though :-)

The biggest point I am not sure now is performance: Isn't a big penalty
associated to this embedding, compared to derivation? Python performance
is not so critical in our application, but I would be uncomfortable having
a factor 10 penalty in methd calling associated to this approach...For now, this will be used for
testing new implementations/extensions, that will be added to the C++
written binding afterwards.

I'd like to thanks the list for the hints, I will post the results of my
experimatations relaxing the assigment to __class__ test if they are
interesting.

Greg.




More information about the Python-list mailing list