inheritance from str or int

Ruggero Turra picture Ruggero Turra · Apr 20, 2010 · Viewed 24.9k times · Source

Why I have problem creating a class inheriting from str (or also from int)

class C(str):
   def __init__(self, a, b):
     str.__init__(self,a)
     self.b = b

C("a", "B")

TypeError: str() takes at most 1 argument (2 given)

tha same happens if I try to use int instead of str, but it works with custom classes. I need to use __new__ instead of __init__? why?

Answer

John La Rooy picture John La Rooy · Apr 20, 2010
>>> class C(str):
...     def __new__(cls, *args, **kw):
...         return str.__new__(cls, *args, **kw)
... 
>>> c = C("hello world")
>>> type(c)
<class '__main__.C'>

>>> c.__class__.__mro__
(<class '__main__.C'>, <type 'str'>, <type 'basestring'>, <type 'object'>)

Since __init__ is called after the object is constructed, it is too late to modify the value for immutable types. Note that __new__ is a classmethod, so I have called the first parameter cls

See here for more information

>>> class C(str):
...     def __new__(cls, value, meta):
...         obj = str.__new__(cls, value)
...         obj.meta = meta
...         return obj
... 
>>> c = C("hello world", "meta")
>>> c
'hello world'
>>> c.meta
'meta'