2016-05-21 9 views
0

)まず、この質問はduplicateであるかもしれませんが、どういうわけかそれらの答えの周りに私の頭を持っていません。私が持っていると言う:子どもの方法を親の方法で飾る方法(

import argparse 
class Parent: 
    def __init__(self): 
     self.parser = argparse.ArgumentParser() 

     self.parser.add_argument("user") 
     # parse the argument 
     self.parser.parse_args() 

class Child(Parent): 
    def __init__(self): 
     # here self.parser is not defined 
     # self.parser.add_argument("password") 
     super().__init__() 
     # here args are already parsed and 
     # self.parser does not include args 
     # self.parser.add_argument("password") 
if __name__ == '__main__': 

    Child() 

これは私が(コマンドラインアプリケーションフレームワークのようなものを書きたいコードの最小限の実施例である私のセットアップは、基本的には次

class Parent: 
    def __init__(self): 
     # do some stuff starting stuff 
     # middle 
     # do some ending stuff 

class Child(Parent): 
    def __init__(self): 
     # do something in the middle of Parent init 

簡単な部分的な回避策があります。私の場合、Parentself.parser.parse_args()をしていないか、なんとか(今は正確に書く方法が分からない)をチェックして、子が引数を追加して子クラスにself.parser.parse_args()を残していれば、可能な1つの愚かなアイデアは、PAを変更することでした家賃の__init__は(INITが、それはおそらく、様々な他の理由から動作しません... None以外のものを返すことができないという事実から一部?)子供を超えるデコレータのように振る舞うと、このような何かを

class Child(Parent): 
    @super.__init__ 
    def __init__(self): 

どのようなアイデアですか、どのパスを選ぶ必要がありますか?そのための私の動機は、そのようなフレームワーク(つまり、Parentを継承するアプリケーションを書くことを意味する)をエンドユーザが望むことです。できるだけ少ない作業を行う必要があります。 。どのようにこれを行うには合理的な方法はありますか?

+0

すべての機能が '__init__'に含まれている場合、なぜこのためにクラスを使用していますか?最後の行は、たとえば、次のようになります。 'Child()。parse()'? – jonrsharpe

+0

@jonrsharpeこれは単なる私の考えではありません。 – quapka

答えて

1

親クラスの '中間'部分を別のメソッドに移動します。これは他の質問への回答の少なくとも一方が行うように説明しますどのような本質的である

class Parent: 
    def __init__(self): 
     self._construct_parser() 
     # parse the argument 
     self.parser.parse_args() 

    def _construct_parser(self): 
     self.parser = argparse.ArgumentParser()  
     self.parser.add_argument("user") 

class Child(Parent): 
    def _construct_parser(self): 
     super()._construct_parser() 
     # add on to self.parser 

;:あなたはその後、だけその子のメソッドオーバーライドすることができます親の__init__のさまざまな部分を別々のメソッドに分割し、それぞれ別々にオーバーライドすることができます。

これをフレームワークにする場合は、特定のフックを追加することもできます。親は、特定のポイントで呼び出す空のメソッドを定義します。子クラスは、特定のステップに参加するために実装できます。 ArgumentParserクラスが構築されており、子クラスがそれに追加できるのはここ、それはなるだろう:

class Parent: 
    def __init__(self): 
     self._construct_parser() 
     # parse the argument 
     self.parser.parse_args() 

    def _construct_parser(self): 
     self.parser = argparse.ArgumentParser()  
     self.parser.add_argument("user") 
     self.update_parser(self.parser) 

    # hook method 
    def update_parser(self, parser): 
     pass 

class Child(Parent): 
    def update_parser(self, parser): 
     # add to parser 

今子クラスでももうsuper()を使用する必要はありません。パーサーを更新するために、フレームワークによって事前に消化された、必要なすべてが渡されます。

+0

ありがとう、素晴らしい。なぜ私はそれがアプリの設定として考えられていたのだろうか(おそらくそれは..)ただの副次的な質問です:あなたはこのコードをあなた自身で使用しますか?いい練習ですか? – quapka

+0

@quapka:私はそれを使うつもりはありません。なぜなら、通常は私の使用のためにすでに利用可能なものがあるからです。より複雑なコマンドラインの必要性のために 'main'()' *関数*でargparseを使うか、 ''クリック ''(http://click.pocoo.org/5/)を使うか、コンテキスト固有のツール[Flask-Script](https://flask-script.readthedocs.io/en/latest/)や[Djangoコマンドを追加する](https://docs.djangoproject.com/ja/1.9/howto/custom-管理コマンド/)。 –

関連する問題