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?
STRs are inherited just like any gene or segment of DNA. Every individual has two alleles per STR, one inherited from each parent.
The bool type inherits from int . Because True and False are (in the sense of inherit from) integers, we can do arithmetic on them. We can even use boolean expressions as numbers (although doing so might result in obscure code).
Python __str__() This method returns the string representation of the object. This method is called when print() or str() function is invoked on an object. This method must return the String object.
Inheritance is when a class is created based on an existing class, and the new class inherits the attributes and methods from the existing class. The new class is usually called “child class”, and the existing class is called “parent class”.
>>> 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'
Inheriting built-in types is very seldom worth while. You have to deal with several issues and you don't really get much benefit.
It is almost always better to use composition. Instead of inheriting str
, you would keep a str
object as an attribute.
class EnhancedString(object): def __init__(self, *args, **kwargs): self.s = str(*args, **kwargs)
you can defer any methods you want to work on the underlying str
self.s
manually or automatically using __getattr__
.
That being said, needing your own string type is something that should give you pause. There are many classes that should store a string as their main data, but you generally want to use str
or unicode
(the latter if you're representing text) for general representation of strings. (One common exception is if you have need to use a UI toolkit's string type.) If you want to add functionality to your strings, try if you can to use functions that operate on strings rather than new objects to serve as strings, which keeps your code simpler and more compatible with everyone else's programs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With