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)