ライブラリにあるクラスを更新したいと思いますが、そのクラスを制御できません(元のソースコードには触れません)。制約番号2:他のユーザーはすでにこの親クラスを継承しており、3番目のクラスから継承するように頼むと、少し煩わしいことになります。だから私は同時に両方の制約を扱わなければならない:親クラスを拡張する必要があるが、継承することはできない。スタティックデコレータを使用した動的装飾
"monkey-patching"に隣接していますが、1つの解決策が最初はもっと意味があるようでした。親クラスのいくつかのメソッドを自分でオーバーライドします。私はそれを行うことができる小さなデコレータを書いた。しかし、いくつかのエラーが発生しました。完全なコードを提供するのではなく、ここに例があります。 (とにかく、そのソースコードについて)ここでは、旧(親クラス)という名前の以下のクラスは、私は触れることができないライブラリであることを考えてみましょう:
単純なクラス、コンストラクタとメソッドをだclass Old(object):
def __init__(self, value):
self.value = value
def at_disp(self, other):
print "Value is", self.value, other
return self.value
パラメータを使って(もう少しテストするため)。これまで何も本当に難しいことはありませんでした。しかし、ここに私のデコレータがこのクラスのメソッドを拡張するために来る:
驚いたことに、これは完全に動作します。 Oldインスタンスを作成し、at_dispメソッドを呼び出すと、新しいメソッドが呼び出されます(古いものを呼び出す)。隠された継承のようなもの。しかしここには本当の挑戦があります:
私たちは古いものを継承しようとします。それはユーザーがやったことです。それはクラッシュ...あなたは新しいオブジェクトを作成した場合
class New(Old):
def at_disp(self, other):
print "That's in New..."
return super(Old, self).at_disp(self, other)
、及びそのat_disp方法を試してみてください。私の「パッチは」彼らが何かをするために必要とせず、あまりにもそれらに適用されるべきです。 super()はOldのat_dispを見つけることができません。奇妙です.NewはOldから直接継承するからです。私の推測は、新しい、置き換えられたメソッドはバインドされていないので、super()はそれを正しく見つけられません。 Old()を直接呼び出してsuper()を置き換えると、すべてが機能します。
誰かがこの問題を解決する方法を知っていますか?なぜそれが起こるのですか?
ありがとうございました!
完璧に、ありがとう!私はそれを逃して恥ずかしいです:S。 –