3

親クラスのインスタンスを返す関数があります。

def generateParent():
   do_stuff
   return Parent(some_parameters)

ここで、次の呼び出しの結果を使用して、Parentのサブクラスを初期化しますgenerateParent()

class Child(Parent):
    def __new__():
        return generateParent(some_other_parameters) 

問題は、ChildのParentからいくつかのメソッドをオーバーライドしてから、プログラムのChildのインスタンスでそれらを呼び出すと、Childの新しいメソッドの代わりに元のParentメソッドが呼び出されることです。私はここで何か間違ったことをしていますか?ここで自分のタスクに正しいデザインを使用していますか?

編集:ParentにもgenerateParent()にもアクセスできません

解決策(@Paul McGuireの回答に感謝します):

class Child(object):
    def __init__(self):
        self.obj = generateParent()

    def __getattr__(self, attr):
        return getattr(self.obj, attr)
4

3 に答える 3

4

はコードではないためgenerateParent、継承の代わりに、包含と委任を使用することをお勧めします。つまり、サブクラスを定義する代わりに、生成されたオブジェクトを含むラッパークラスを定義し、必要に応じてメソッド呼び出しをそのクラスに転送しますが、ラッパーに新しい動作または変更された動作を追加できます。

この質問では、OPにも同様の状況があり、ライブラリでクラスが生成されましたが、クラスを拡張したり、クラスの動作を変更したりしたいと考えていました。その質問でラッパークラスを追加した方法を見てください。ここで同様のことを行うことを検討してください。

于 2013-01-06T00:41:26.587 に答える
1

これを行う1つの方法は次のとおりです。

def generateChild(params):
    p = generateParent(params)
    p.__class__ = Child
    return p

class Child(Parent):
    # put method overrides etc here

childinstance = generateChild(some_params)
于 2013-01-06T00:09:22.443 に答える
1
  1. generateParentおそらく、他のクラスのインスタンスを作成できるようにしたいでしょう。

    def generateParent(cls=Parent):
        do_stuff
        return cls(some_parameters)
    

    これで、子オブジェクトが作成されます。

    child = generateParent(Child)
    
  2. または、Parentとそのすべての派生クラスで共通の初期化コードを使用したいですか?

    class Parent(object):
        def __init__(self):
            do_stuff
            # init from some_parameters
    
    class Child(Parent):
        # blah..
    
  3. 作成した親オブジェクトから情報をコピーできるように子オブジェクトを作成します。

    class Child(Parent):
        def __init__(self):
            model_parent = generateParent()
            self.a = model_parent.a
            self.b = model_parent.b
            # etc.
    
于 2013-01-06T00:50:49.787 に答える