I have the following code:
class Demo:
def __new__(self):
self.__init__(self)
print("Demo's __new__() invoked")
def __init__(self):
print("Demo's __init__() invoked")
class Derived_Demo(Demo):
def __new__(self):
print("Derived_Demo's __new__() invoked")
def __init__(self):
print("Derived_Demo's __init__() invoked")
def main():
obj1 = Derived_Demo()
obj2 = Demo()
main()
I'm trying to understand the order of execution:
__new__ in the derived class is called first
why doesn't _init_ in the derived class called next?
Your code is fundamentally broken, which is why __init__
isn't being invoked as expected.
Per the docs for __new__
:
If
__new__()
does not return an instance of cls, then the new instance’s__init__()
method will not be invoked.
Your __new__
doesn't explicitly return anything, so it's returning None
.
If you write it correctly (including removing explicit calls to __init__
within __new__
, and explicitly delegating up the inheritance chain for Derived_Demo
's __new__
and __init__
), you code will work as expected:
class Demo:
def __new__(cls):
print("Demo's __new__() invoked")
return super().__new__(cls)
def __init__(self):
print("Demo's __init__() invoked")
class Derived_Demo(Demo):
def __new__(cls):
print("Derived_Demo's __new__() invoked")
return super().__new__(cls)
def __init__(self):
print("Derived_Demo's __init__() invoked")
super().__init__()
def main():
obj1 = Derived_Demo()
obj2 = Demo()
main()
Which outputs:
Derived_Demo's __new__() invoked
Demo's __new__() invoked
Derived_Demo's __init__() invoked
Demo's __init__() invoked
Demo's __new__() invoked
Demo's __init__() invoked
where super()
based dispatch completely runs all the __new__
(s) then all the __init__
(s) are run on the resulting object produced by __new__
.