I'm trying to replace the __init__
method of a derived class.
But for some reason, the original __init__
is called, although the __dict__
shows the replaced function.
If I call the __init__
manually, the replaced function is called...
Example code:
class TheBase(object):
def __new__(cls, *args, **kwargs):
newInstance = super(TheBase, cls).__new__(cls)
newInstance._origInit = newInstance.__init__
newInstance.__init__ = newInstance._myInit
print "Replaced the init of {} with {} ({})".format(newInstance, newInstance._myInit, id(newInstance._myInit))
print newInstance.__dict__
return newInstance
def _myInit(self, *args, **kwargs):
print "TheBase _myInit of {} ({})".format(self, id(self.__init__))
self._origInit(*args, **kwargs)
self._afterInit()
def _afterInit(self):
print "Init has passed..."
# Do some magic here...
class MyDerived(TheBase):
def __init__(self, great=False):
TheBase.__init__(self)
print "MyDerived __init__ of {} ({})".format(self, id(self.__init__))
class MyDerived2(MyDerived):
def __init__(self):
MyDerived.__init__(self, great=True)
print "MyDerived2 __init__ of {} ({})".format(self, id(self.__init__))
sd = MyDerived()
print "--------------- manual init --------------"
sd.__init__()
Result:
Replaced the init of <__main__.MyDerived object at 0x00385390> with <bound method MyDerived._myInit of <__main__.MyDerived object at 0x00385390>> (35356224)
{'__init__': <bound method MyDerived._myInit of <__main__.MyDerived object at 0x00385390>>, '_origInit': <bound method MyDerived.__init__ of <__main__.MyDerived object at 0x00385390>>}
MyDerived __init__ of <__main__.MyDerived object at 0x00385390> (35213640)
--------------- manual init --------------
TheBase _myInit of <__main__.MyDerived object at 0x00385390> (35213640)
MyDerived __init__ of <__main__.MyDerived object at 0x00385390> (35213640)
Init has passed...
In my real world project, I want to start a thread (in the base class) but this must not run until the __init__
of the derived classes have finished. Because this is part of some refactoring, and the already existing derived classes are developed by other persons, I can’t modify their code (and start the thread there).
Replacing the __init__
in the class rather than the instance is also not possible, because sometimes the derived class is derived again (class MyDerived2(MyDerived):
)
Has anyone an idea, why the original __init__
is called (and how to avoid that), or another way to solve the problem?