Home > Software design >  python primitive class constructor - int() can't convert non-string with explicit base -
python primitive class constructor - int() can't convert non-string with explicit base -

Time:08-21

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)

  • Related