Code design for a sub-class of built-ins
Bruno Desthuilliers
onurb at xiludom.gro
Tue Jul 4 13:26:36 EDT 2006
Steven D'Aprano wrote:
> I'm having problems with sub-classes of built-in types.
>
> Here is a contrived example of my subclass. It isn't supposed
> to be practical, useful code, but it illustrates my problem.
>
> class MyStr(str):
> """Just like ordinary strings, except it exhibits special behaviour
> for one particular value.
> """
> magic = "surprise"
> def __init__(self, value):
> str.__init__(self, value)
You don't need to override __init__ here.
> def __len__(self):
> if self == self.magic:
> print "Nobody expects the Spanish Inquisition!"
> return str.__len__(self)
> def upper(self):
> if self == self.magic:
> print "Nobody expects the Spanish Inquisition!"
> return str.upper(self)
> # and so on for every last string method...
My my my....
>
> The obvious problem is, I have to create a custom method for every string
> method --
which makes subclassing almost useless - except to pass isinstance() tests.
> and if strings gain any new methods in some future version of
> Python, my subclass won't exhibit the correct behaviour.
You could replace subclassing by composition/delegation using the
__getattr__ hook, but this would break tests on type/class :(
Or you could keep subclassing and use the __getattribute__ hook, but
this is more tricky and IIRC may have negative impact on lookup perfs.
Or you could use a metaclass to decorate (appropriate) str methods with
a decorator doing the additional stuff.
choose your poison !-)
> Here's a slightly different example:
>
> class MyInt(int):
> """Like an int but with special behaviour."""
> def __init__(self, value, extra):
> int.__init__(self, value=None)
> self.extra = extra
Won't work. You need to override the __new__ staticmethod. Look for
appropriate doc here:
http://www.python.org/download/releases/2.2.3/descrintro/#__new__
(FWIW, read the whole page)
(snip)
> Looks like my __init__ isn't even being called here. Why not, and how do I
> fix this?
cf above
> Is there a way to subclass built-in types without needing to write the
> same bit of code for each and every method?
cf above
> Am I approaching this the wrong way? Is there a better design I could be
> using?
probably !-)
HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list