Search code examples
pythonstringinheritanceintegernew-operator

inheritance from str or int


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)

the 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?


Solution

  • >>> 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'