I recently found a need to subclass the builtin type unicode and add some additional properties. To instantiate I wanted to pass in a big, ugly object and get a unicode object back. After trying fruitlessly to override __init__, I finally read up on
the Python data model. Turns out I needed to override both __new__ and __init__.
Here's a quick example:
class Equation(unicode):
def __new__(cls, i1, i2, i3):
eq = u"%(i1)s + %(i2)s = %(i3)s" % {'i1':i1, 'i2':i2, 'i3':i3}
return unicode.__new__(cls, eq)
def __init__(self, i1, i2, i3):
self.__is_valid = False
if i1 + i2 == i3:
self.__is_valid = True
@property
def is_valid(self):
return self.__is_valid
If I instantiate this with equation = Equation(1, 2, 3), equation will act like a unicode object with the value u'1 + 2 = 3', and equation.is_valid will be True. Similarly, equation = Equation(2, 2, 5) will look like u'2 + 2 = 5', and is_valid will be False.
I doubt I'll forget this, but at least now I have it recorded somewhere.