enhancing/wrapping an existing instance of a duck
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Mon Sep 1 14:27:29 EDT 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