Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting from int object

I have a class that inherits from int, in my class init function I am not calling the parent init function, but still somehow there is a value when I use the parent (int) methods, which means I think that the parent init was also called?

for example:

class NumberWithCall(int):
    def __init__(self, number):
        pass

print(NumberWithCall(8))

will return 8

I thought that maybe the parent constructor is called implicitly, but in this code I saw it is not:

class parent:
    def __init__(self):
        print("in parent init")

class son(parent):
    def __init__(self):
        print("in son init")

son()

will return: in son init

like image 984
Eyal Gruber Avatar asked Oct 24 '25 05:10

Eyal Gruber


1 Answers

I intend to show you what happens roughly. By the way I over simplified this.

first think about implementing __call__ inside your class. It enables the instance of the class to be callable.

Now we know that classes are instances themselves -> of type type:

class A:
    pass

print(isinstance(A, type))  # True

So there has to be a __call__ method in "their" class(better to say metaclass) and of course there is one in type.

When you put parentheses in front of you class, you are actually calling this method with the given argument (here 8). What it does, first(here some another things happens but we ignored) calls the __new__ method with the argument you passed to the __call__, this method returns an instance of int, then __init__ will get called as an instance method on the newly created int object.

So the way your class works is because of this:

class NumberWithCall(int):
    def __new__(cls, number):
        created_object = super().__new__(cls, number)
        return created_object

    def __init__(self, number):
        print(f'init is called with number={number}')


print(NumberWithCall(8))

You inherited this __new__ from int and so yes, as @johnrsharpe pointed out in the comment, "Immutable types in Python generally do the work in __new__, not __init__

like image 81
SorousH Bakhtiary Avatar answered Oct 25 '25 18:10

SorousH Bakhtiary