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 '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list