派生クラスの__init__
メソッドを置き換えようとしています。 何らかの理由で、元の__init__
が呼び出されますが、__dict__
には置き換えられた機能が示されています。 私は手動で__init__
を呼び出した場合、置き換え機能が... 例コードと呼ばれる:作成したオブジェクトの__init__を__new__コンストラクタに置き換えます。
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__
が呼び出される(および回避する方法、なぜ誰もアイデアを持っていますそれ)、または別の方法で問題を解決しますか?
おかげで、私はそれを試してみました。 2番目の継承では機能しません。第1または第2の継承クラスは、期待どおりに動作しません(両方のレベルが時々インスタンス化されます)。 –
@AlexG。上記を見てください。あなたが何をしているのですか? – ecatmur
__init__が__init__を呼び出すため、「再帰RuntimeError」が最大になってしまいました。 –