1
我試圖替換派生類的__init__
方法。 但由於某種原因,原來的__init__
被調用,雖然__dict__
顯示替換函數。 如果我手動調用__init__
,替換函數調用... 示例代碼:在__new__構造函數中替換已創建對象的__init__
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__()
結果:
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...
在我的現實世界中的項目,我想啓動一個線程(在基類),但只有在派生類的__init__
完成後才能運行。因爲這是某些重構的一部分,並且已有的派生類是由其他人開發的,所以我不能修改它們的代碼(並在那裏啓動線程)。
班上更換__init__
而非實例也是不可能的,因爲有時派生類又派生(class MyDerived2(MyDerived):
)
有沒有人一個想法,爲什麼原來__init__
被稱爲(以及如何避免那),還是另一種解決問題的方式?
感謝您的提示,但我已經試過了。它不適用於第二個繼承。第一個或第二個繼承類無法按預期工作(有時會將這兩個級別實例化)。 –
@AlexG。看看上面的內容;那是你在追求什麼? – ecatmur
再次感謝,它看起來不錯,但我得到了「最大遞歸RuntimeError」,因爲派生的__init__調用了它們的超級__init__ –