2016-05-04 27 views
0

私はPython3でサブ/スーパークラスを初期化する最良の方法を理解しようとしています。ベースクラスとサブクラスの両方には6つのパラメータがあり、そのすべてがコマンドライン引数から解析されます。私はサブサブクラスを持っている場合(私はなる)、物事は本当に毛深い取得初期化引数をスーパークラスに渡すためのベストプラクティス?

class Base: 
    def __init__(self, base_arg1, base_arg2, base_arg3): 

class Sub(Base): 
    def __init__(self, sub_arg1, sub_arg2, sub_arg3, 
        base_arg1, base_arg2, base_arg3): 
    super().__init__(self, base_arg1, base_arg2, base_arg3) 

main(): 
    # parse args here 
    options = parser.parse_args() 

    obj = Sub(options.sub_arg1, options.sub_arg2, options.sub_arg3, 
       options.base_arg1, options.base_arg2, options.base_arg3) 

これを実装するための明白な方法は、一度にすべての引数を解析し、そして、それらのすべてを渡すことです連続するsuper()を介して渡された引数のリストの項。 ()が呼び出されます。

しかし、argparse.parse_known_args()は、別のパスを提供していますように私には発生します。私は、各サブクラスは、それが/認識する必要のある引数を解析し、階層までの残りの引数を渡すかもしれない:

class Base: 
    def __init__(self, args): 
     base_options = base_parser.parse_known_args(args) 

class Sub(Base): 
    def __init__(self, args): 
     (sub_options, other_args) = sub_parser.parse_known_args(args) 
     super().__init__(self, other_args) 

main(): 
    obj = Sub(sys.argv) 

これはAPIの観点から見るときれいです。しかし、私はそれがPythonで実現される方法のいくつかの信念に違反していると想像することができ、あらゆる理由で悪い考えです。私のウェブ検索では、どちらの方法でも例が示されていません。スタックオーバーフローの強大な、すべてを知っている人が、これを行う正しい方法を理解するのに役立つでしょうか?

答えて

0

argparse.pyコードを参照してください。 ArgumentParser_ActionsContainerのサブクラスです。 actionsはすべてActionのサブクラスです。

あなたは順番にに渡し_StoreAction

parser.add_argument('foo', action='store_action', ...) 
ほとんど *argsなどのパラメータが渡され

、および**kwargsを呼び出すとそのsupper(いくつかのデフォルト値などを設定した後)。

インポートすることを意味し、スクリプトに沿ってスタンドとして実行されないモジュールとして、ブロックif __name__....はありません。しかし、しばしば、テストコードを呼び出すためのブロックを含めることにします。これは、コマンドラインパーサーを置くか、少なくともそれを呼び出す場所です。 ifは本体の関数で定義されているかもしれませんが、通常はモジュールをインポートするときに呼び出されるべきではありません。

一般的に、​​はスクリプトツールです。クラス定義の一部ではありません。新しい機能を追加するには、サブクラス化ArgumentParserを使用している場合を除きます。

https://pypi.python.org/pypi/placもご覧ください。このパッケージは​​と異なるインターフェースを提供しています。このパーサのサブクラス化の良い例です。

0

ありがとうhpaulj!私はあなたの反応が私に役立つと思っています。私はトップレベルのすべてのオプションを解析してから、オプションの名前空間を渡して、各サブクラスが必要なものを取り出せるようにします。他のアプローチと比較して、手の平の種類は単純です:

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

class Sub(Base): 
    def __init__(self, options): 
     super().__init__(self, options) # initialize base class 
     sub_arg1 = options.sub_arg1 
     sub_arg2 = options.sub_arg2 

main(): 
    options = parser.parse_args() 
    obj = Sub(options) 
関連する問題