異なるクラスの異なるインスタンスにある 2 つのメソッドを、クラスの 1 つのインスタンスにマージする必要があります。
たとえば、次の 2 つのクラスを定義します。
class A:
def __init__(self):
self.name = "a"
def print_name(self):
print(self.name)
class B:
def __init__(self):
self.name = "b"
def print_name(self):
print(self.name)
そして、別のオブジェクト c を作成しようとします。その print_name メソッドは a.print_name() と b.print_name() の結果を返す必要があるため、次のことを試しました。
a = A()
b = B()
c = A()
c.name = "c"
c.print_name_1 = a.print_name
c.print_name_2 = b.print_name
def final_print(self):
self.print_name_1()
self.print_name_2()
c.print_name = MethodType(final_print, c)
c.print_name()
期待される出力:
c
c
しかし、私は次のように思います:
a
b
ここで説明されているように、types.MethodType を使用しようとしましたが、2 つの引数を取るある種のメソッドが作成されます。最初の引数は 'a' インスタンスで、2 番目の引数は 'c' インスタンスになります。
それを適切に行うための助けはありますか?
2
インスタンスごとにメソッドをオーバーライドすると、クラスのすべてのインスタンスに均一のインターフェイスを提供するというクラスの目的が損なわれます。
– チェプナー
2020 年 9 月 4 日 18:24
私の目標は、他の 2 つのオブジェクトをマージして新しいオブジェクトを作成することですが、別の方法でそれを行う方法がわかりません
– ブリーキー
2020 年 9 月 4 日 18:26
2
c は A のインスタンスであるべきですか、それとも本当に新しいクラスのインスタンスであるべきですか?また、A と B は本当に別のクラスである必要があるのでしょうか、それとも a と b は、name 属性の値が異なるだけで同じクラスのインスタンスであってもよいのでしょうか?
– チェプナー
2020 年 9 月 4 日 18:29
a、b、c は同じクラスから継承しており、これを親と呼びますが、これらは異なるメソッドを持つ異なるクラスです
– 気まぐれな
2020 年 9 月 4 日 20:39
------------------------
この回答のおかげで、なんとか成功することができました。メソッドの __func__ 属性を使用しています。コードは次のとおりです:
c.name = "c"
c.print_name_1 = MethodType(lambda instance: copy.deepcopy(a.print_name).__func__(instance), c)
c.print_name_2 = MethodType(lambda instance: copy.deepcopy(b.print_name).__func__(instance), c)
def final_print(self):
self.print_name_1()
self.print_name_2()
c.print_name = MethodType(final_print, c)
c.print_name()
6
1
これは機能しますが、おそらく、達成したい最終目標に対する正しい解決策ではありません。
– トリプリー
2020 年 9 月 6 日 17:42
私の目的をより正確に説明すると、親クラス Parent と、関数 print_name の独自の実装を持つ A および B という 2 種類の親を作成することです。ここでは、A と B をマージして、同じ名前 (つまり print_name) の関数を持つ新しいクラスまたはインスタンス (上記のコードでは c) を動的に作成したいと考えています。この関数は、最初に A で定義されたメソッド print_name を実行する必要があります。 、次に B で定義されたメソッド print_name です。ただし、これらの関数の self 引数はインスタンス c を参照します。それでは、これらのメソッドを 1 つに動的にマージする方法をご存知ですか?
– ブリーキー
2020 年 9 月 7 日 18:10
それはまだクレイジーです。なぜそれをしたいのですか? A と B に異なる名前のメソッドがあると、別の名前でメソッドをディスパッチするラッパーを簡単に作成できるため、A では def method(): return(a_method)、B では def method: return(b_method) になります。 。 C では、A と B の両方と def メソッドを簡単に継承できます。 a_method(); b_method() などを返します。
– トリプリー
2020 年 9 月 7 日 18:14
1
余談ですが、ミックスインも参照してください。
– トリプリー
2020 年 9 月 7 日 18:14
1
はい、はい。A: def print_name(): return a_specific_print_name() および B: def print_name(): return b_ specific_print_name() のように定義してから、C で def print_name(): a_specific_print_name(); のように定義します。 b_specific_print_name()
– トリプリー
2020 年 9 月 8 日 6:18