2009-04-27 9 views
5

共通の親を共有するクラスのグループの初期化プロセスは、共通パート1、クラス固有パート、共通パート2の3つのパートに分けられます。現在、最初の2つの部分は、それぞれの子クラスの__init__関数から呼び出されるが、第2の共通の部分は、例えば、別々に 呼び出す必要がありますされています継承されたPythonクラスで一般的な初期化後タスクを実行するにはどうすればよいですか?

class BaseClass: 
    def __init__(self): 
    print 'base __init__' 
    self.common1() 

    def common1(self): 
    print 'common 1' 

    def finalizeInitialization(self): 
    print 'finalizeInitialization [common2]' 


class Subclass1(BaseClass): 
    def __init__(self): 
    BaseClass.__init__(self) 
     self.specific() 

    def specific(self): 
    print 'specific' 


if __name__ == '__main__': 
    s = Subclass1() #Don't forget to finalize the initialization 
    s.finalizeInitialization() # now the object is fully initialized 

はfinalizeInitializationを(呼び出すために持っていない方法はあります) ?

EDIT finalizeInitialization()の呼び出しをSubclass1の__init__(S.Lott's answerのように)に転送できます。これは人生を楽にしますが、まだ "コンストラクタ"内で初期化を完了することを忘れてはいけません。いずれにしても、私が探している完全な初期化を強制する方法はありません。

答えて

6

バージョン1 - すべてを委任します。

class Subclass1(BaseClass): 
    def __init__(self): 
     super(Subclass1, self).__init__() 
     self.specific() 
     super(Subclass1, self).finalizeInitialization() 

バージョン2 - デリゲートワンステップサブクラスのinitからfinalInitilazationを呼び出すと間違って何

class BaseClass: 
    def __init__(self): 
     print 'base __init__' 
     self.common1() 
     self.specific() 
     self.finalizeInitialization() 

    def common1(self): 
     print 'common 1' 

    def finalizeInitialization(self): 
     print 'finalizeInitialization [common2]' 

    def specific(self): 
     # two choices: 
     # if this is "abstract": raise an exception 
     # if this is "concrete": pass 
+0

ありがとうございます。訂正のため編集を参照してください –

+0

私はバージョン2を採用しています。ありがとう –

0

class BaseClass: 
     def __init__(self): 
      print 'base __init__' 
      self.common1() 

     def common1(self): 
      print 'common 1' 

     def finalizeInitialization(self): 
      print 'finalizeInitialization [common2]' 


    class Subclass1(BaseClass): 
     def __init__(self): 
      BaseClass.__init__(self) 
      self.specific() 
      BaseClass.finalizeInitialization(self) 

     def specific(self): 
      print 'specific' 


    if __name__ == '__main__': 
     s = Subclass1() #Don't forget to finalize the initialization 
     s.finalizeInitialization() # now the object is fully initialized 
0

あなたが特定の順序で複数のメソッドを呼び出す必要がある場合、それは通常、設計は(それは実装の詳細をリークしています)そもそもの問題を有することを意味します。だから、私はその目的のために努力するつもりです。

一方、人々がクラスから派生し、初期化を変更する必要がある場合は、その意味を理解しておく必要があります。これは、通常のAPIでは望んでいないものです。あるいは、最終的な初期化について防御的であり、それに依存するメソッドでコールされていることを確認することもできます(呼び出すか、そうでない場合に例外を発生させる)。

10
救助に

テンプレートメソッドデザインパターン:S.ロットのアプローチと同様に

class BaseClass: 
    def __init__(self, specifics=None): 
     print 'base __init__' 
     self.common1() 
     if specifics is not None: 
      specifics() 
     self.finalizeInitialization() 

    def common1(self): 
     print 'common 1' 

    def finalizeInitialization(self): 
     print 'finalizeInitialization [common2]' 


class Subclass1(BaseClass): 
    def __init__(self): 
     BaseClass.__init__(self, self.specific) 

    def specific(self): 
     print 'specific' 
1

、上書き(あるいは呼び出す)する派生クラス一般的な方法について(__init__をオーバーライドする短い)方法はありません除いて:あなたはしないすべてのサブクラスのインスタンスを作成するとき、それはAttributeErrorを上げても大丈夫ではない場合

class BaseClass: 
    def __init__(self): 
     def common(): 
      print "common initialization..." 

     def final(): 
      print "common finalization..." 

     common() 
     self.specific() 
     final() 

    def final_init(self): 
     print "BaseClass.final_init" 


class Subclass1(BaseClass): 

    def specific(self): 
     print "Subclass1.specific" 

あなたはBaseClassspecificのデフォルトの実装を提供する場合があります独自の実装を提供します。

関連する問題