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
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__
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With