Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 630
Ruggero Turra Avatar asked Apr 20 '10 08:04

Ruggero Turra


People also ask

Are str inherited?

STRs are inherited just like any gene or segment of DNA. Every individual has two alleles per STR, one inherited from each parent.

Can you inherit from int Python?

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).

What is the __ str __ method in Python?

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.

How does inheritance work in Python?

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”.


2 Answers

>>> 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' 
like image 182
John La Rooy Avatar answered Sep 22 '22 03:09

John La Rooy


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.

like image 37
Mike Graham Avatar answered Sep 22 '22 03:09

Mike Graham