I have read contructor theory in Python explaining that constructor inheritance is possible in Python. I have inherited int class into my class a. In principle, constructor in child class have highest priority. Why constructor of my child class does not evoke?
class a(int):
def __init__(self,value1,value2):
self.value1=value1
self.value2=value2
obj1=a(2,2)
TypeError: int() can't convert non-string with explicit base
CodePudding user response:
int is an immutable type in Python. That means that is does not use __init__, but __new__.
The difference between __init__ and __new__ is that __init__ is an initializer, while __new__ is a constructor. So, when __init__ is called, your instance has already been created. In order to implement immutable objects, you want the ability to "cancel" creating a new object in some cases. For instance, when int(1) is performed, it would make little sense to create a new instance equal to 1. In stead, the existing instance can simply be returned.
So, in theory, you could do something like this:
class a(int):
def __new__(cls, value1, value2):
self = super().__new__(cls)
self.value1 = value1
self.value2 = value2
return self
The error you are getting is because a(2, 2) calls int.__new__ with two arguments: 2 and 2. The two-argument form of int.__new__ expects the first argument to be a str in a base specified by the second argument.
If you want to experiment with inheritance in Python, you might find it easier to use your own defined classes -- inheritance involving built-in classes can be tricky at times.
One additional detail I wanted to add: in my experience, you usually do not want to replace the initializer or constructor of your parent class. In stead, you probably want to extend it, like I did in my example above using the call to super().__new__. But then again, there might be valid use cases.
CodePudding user response:
I believe that since int is immutable; the __init__ cannot be changed, so a(2, 2) still ends up looking calling like int(2, 2)
