enhancing/wrapping an existing instance of a duck

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Mon Sep 1 20:27:29 CEST 2008


Neville Dempsey a écrit :
> Basically I have an existing (maybe a rather large and complicated
> (existing) instance) that
> I want to add new member to.

I suppose you mean "attributes" ?

> Cheers
> N
> 
> Hacks/attempts follow:
> 
> from math import sqrt
> 
> ############ try2 ############
> duck_obj = [ i*i for i in range(25) ] # OR a large sparse matrix
> 
> # I "want" to an a useful property, eg length, and retain the ducks
> existing properties.
> # I COULD try...
> setattr(duck_obj,"length",lambda: sqrt(sum(*duck_obj)))

Won't work on a list.

> print duck_obj.length() # returns 70
> duck_obj[0]=70+71
> print duck_obj.length() # returns 71

You obviously didn't try the above code.

Traceback (most recent call last):
   File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'length'



Also and FWIW, in Python, the "sizeable" protocol is implemented using a 
__len__ method, that will get called by the generic len(sizeable) function.

> ############ try2 ############
> # **BUT** I'd rather encapsulate a the original instance somehow.
 >
> # I presume that I could define a class to do this somehow?
> duck_obj = [ i*i for i in range(25) ] # OR a LargeSparseMatrix()
> 
> dec = Vec(duck_obj) ???
> print dec.length() # returns 70
> duck_obj[0]=70+71 # original "large and complicated duck instance"
> print dec.length() # returns 71
> 
> Any hints on how I need to define Vec so that any kind of duck_obj can
> be decorated/wrapped/encapsulated.

Depends on the type of duck_obj. In the above case, I'd inherit from 
list and override __len__ :

 >>> import math
 >>> class Vec(list):
...     def __len__(self):
...         return math.sqrt(sum(self))
...
 >>> Vec(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 >>> len(Vec(range(10)))
6



More information about the Python-list mailing list