S
Steven D'Aprano
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)
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...
The obvious problem is, I have to create a custom method for every string
method -- and if strings gain any new methods in some future version of
Python, my subclass won't exhibit the correct behaviour.
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
def __add__(self, other):
if self.extra is None:
return int.__add__(self, other)
else:
return int.__add__(self, other) + self.extra
# and again with all the other methods
This one doesn't even work!
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: int() can't convert non-string with explicit base
Looks like my __init__ isn't even being called here. Why not, and how do I
fix this?
Is there a way to subclass built-in types without needing to write the
same bit of code for each and every method?
Am I approaching this the wrong way? Is there a better design I could be
using?
Thanks,
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)
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...
The obvious problem is, I have to create a custom method for every string
method -- and if strings gain any new methods in some future version of
Python, my subclass won't exhibit the correct behaviour.
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
def __add__(self, other):
if self.extra is None:
return int.__add__(self, other)
else:
return int.__add__(self, other) + self.extra
# and again with all the other methods
This one doesn't even work!
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: int() can't convert non-string with explicit base
Looks like my __init__ isn't even being called here. Why not, and how do I
fix this?
Is there a way to subclass built-in types without needing to write the
same bit of code for each and every method?
Am I approaching this the wrong way? Is there a better design I could be
using?
Thanks,