1

私はクラスを持っていBaseます。クラスでその機能を拡張したいと思いDerivedます。私は書く予定でした:

class Derived(Base):
  def __init__(self, base_arg1, base_arg2, derived_arg1, derived_arg2):
    super().__init__(base_arg1, base_arg2)
    # ...
  def derived_method1(self):
    # ...

すでにインスタンスがあり、それに基づいてインスタンスBaseを作成したい場合があります。つまり、オブジェクトを共有する(最初から再作成しない) インスタンスです。それを行うための静的メソッドを書くことができると思いました:DerivedDerivedBase

b = Base(arg1, arg2) # very large object, expensive to create or copy
d = Derived.from_base(b, derived_arg1, derived_arg2) # reuses existing b object

しかし、それは不可能のようです。これを機能させる方法が見つからないか、または (より可能性が高い) 機能できない大きな理由を見逃しているかのどちらかです。誰かがそれがどれであるか説明できますか?

[もちろん、継承ではなく構成を使用すれば、これはすべて簡単に実行できます。Baseしかし、すべてのメソッドをDerivedthroughに委譲することは避けたいと思っていました__getattr__。]

4

3 に答える 3

2

Baseあなたのクラスがbase_arg1,で何をしているかに依存してくださいbase_arg2.

class Base(object):
    def __init__(self, base_arg1, base_arg2):
        self.base_arg1 = base_arg1
        self.base_arg2 = base_arg2
        ...

class Derived(Base):
    def __init__(self, base_arg1, base_arg2, derived_arg1, derived_arg2):
        super().__init__(base_arg1, base_arg2)
        ...

    @classmethod
    def from_base(cls, b, da1, da2):
        return cls(b.base_arg1, b.base_arg2, da1, da2)
于 2012-12-10T11:09:55.260 に答える
1

アレクセイの答え(私の+1)に対する別のアプローチは、 base_arg1引数に基本オブジェクトを渡し、基本オブジェクトを渡すために誤用されたかどうかを確認することです(基本クラスのインスタンスである場合)。もう 1 つの引数は、技術的にオプション (たとえばNone) にすることができ、コード内で決定されたときに明示的にチェックできます。

違いは、引数の型だけが、2 つの可能な作成方法のどれを使用するかを決定することです。これは、オブジェクトの作成をソース コードで明示的にキャプチャできない場合に必要です (たとえば、一部の構造に引数のタプルが混在しており、一部は初期値を持ち、一部は既存のオブジェクトへの参照を持っています。その場合、次のようになります。おそらくキーワード引数として引数を渡す必要があります:

d = Derived(b, derived_arg1=derived_arg1, derived_arg2=derived_arg2)

更新:内部構造を初期クラスと共有するには、両方のアプローチを使用できます。ただし、オブジェクトの 1 つが共有データを変更しようとすると、おかしなことが起こる可能性があるという事実に注意する必要があります。

于 2012-12-10T11:26:55.800 に答える
1

ここで明確にするために、コードで答えます。pepr はこの解決策について語っていますが、コードは常に英語よりも明確です。この場合、Base はサブクラス化されるべきではありませんが、Derived のメンバーである必要があります。

class Base(object):
    def __init__(self, base_arg1, base_arg2):
        self.base_arg1 = base_arg1
        self.base_arg2 = base_arg2

class Derived(object):
    def __init__(self, base, derived_arg1, derived_arg2):
        self.base = base
        self.derived_arg1 = derived_arg1
        self.derived_arg2 = derived_arg2

    def derived_method1(self):
        return self.base.base_arg1 * self.derived_arg1
于 2012-12-11T06:11:02.740 に答える