2016-12-28 13 views
1

さまざまなサブパーザーを持つPythonモジュールの引数パーサを作成しています。Python argparse:ヘルプ文字列内のサブパーザープログラムの名前を取得します。

from argparse import ArgumentParser 
parser = ArgumentParser(prog = 'master') 
parser1 = ArgumentParser(help = None) 
parser1.add_argument('foo', type = int, help = 'Number of times to process %(prog)s') # Line of interest 
parser2 = ArgumentParser(help = None) 
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number') 
parser3 = ArgumentParser(help = None) 
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text') 
subparsers = parser.add_subparsers() 
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2]) 
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3]) 
parser.parse_args('prog1 -h'.split()) 

所望の出力は、私はこの正確なセットアップを使用する場合は、私が代わりにmaster prog1を得る

usage: master prog1 [-h] [--bar BAR] foo 

positional arguments: 
    foo   Number of times to process prog1 

optional arguments: 
    -h, --help  show this message and exit 
    --bar   Start at this number 

ようなものになるだろう:私の目標は、その引数のコンストラクタが複数の子どもたちに渡された共有の議論を持っていることですfooのヘルプ文字列にprog1があります。希望の結果を得るために、#Line of interestと記された行で何を変更する必要がありますか?

答えて

0

これはあなたの質問に対する直接的な回答ではありませんが、私はあなたがしようとしているものに対してClick_を使用します。

Click_の三点で:

  1. コマンド
  2. 自動ヘルプページ生成
  3. の任意のネストは、私は何が起こっているかを説明することができ、実行時
0

のサブコマンドの遅延ロードをサポートし、ソリューションを提供できない可能性があります。

sp1.progは、usageの形式とヘルプラインの%(prog)sという値の両方で使用されています。そしてそれはusage行を念頭に置いて作られています。

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2]) 

===============はパーサを作成し、parentsから引数を追加します。 add_parserclass _SubParsersActionのメソッドです(サブパーザのActionクラス)。そして、そのパーサーのprog属性を使用して作成されます。

 if kwargs.get('prog') is None: 
     kwargs['prog'] = '%s %s' % (self._prog_prefix, name) 

あなたはprint(sp1.prog)でこの属性を見ることができるはずです(私は「マスターPROG1」期待)。これは、usage行とヘルプ行のいずれかで使用される値で、%(prog)sです。

subparsers._prog_prefixは、parser.prog(詳細はadd_subparsersコードを参照)に由来します。

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1') 

help行の文字列を修正する必要があります。しかし、あなたはまた、progパラメータを指定することができます。しかし、それはまた、usageの文字列を変更します。私はあなたにも、使用中にそれを変更することなく、ヘルプラインでprogを変更することができるとは思わないHelpFormatterに手術を行わず

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1', usage='master prog1 ...') 

はまたsubparser明示usageを与えることができます。

の方法ではprog1 fooのヘルプラインを変更することはできません。prog2 fooも変更する必要はありません。 parentsはアクションオブジェクトを参照でコピーするため、2つのサブパパラはfooアクションオブジェクトを共有します。

多くの場合、少なくともこの引数についてはparentsアプローチを放棄し、名前をハードコードする必要があります。複数のサブパーザに引数を追加する必要がある場合は、それを容易にするための小さなユーティリティ関数を記述します。 parentsのメカニズムは(通常)便利なもので、入力/編集を省くことができます。

===================

この修正されたスクリプトは

parser = ArgumentParser(prog = 'master') 

parser1 = ArgumentParser(add_help = False) 
fooarg=parser1.add_argument('foo', type = int, help = 'foo prog: %(prog)s') # Line of interest 
parser2 = ArgumentParser(add_help = False) 
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number') 
parser3 = ArgumentParser(add_help = False) 
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text') 

subparsers = parser.add_subparsers(prog='subparsers') 
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='name1') 
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3]) 

#parser.print_help() 

# fooarg is an Action for both subparsers 
# print(fooarg.help) 
# fooarg.help = 'FOO HELP' 

print('==>sp1 prog:', sp1.prog) 
sp1.print_help() 
print('==>sp2 prog:', sp2.prog) 
sp2.print_help() 

sp1.prog = 'custom' 
sp1.print_help() 

# addition 
fooarg.default = 'default' 
fooarg.metavar = 'META' 
fooarg.help = 'prog: %(prog)s, dest=%(dest)s, nargs=%(nargs)s, type=%(type)s, default=%(default)s' 
sp1.print_help() 

私のポイントを説明します。この最後のビットがアクション属性の束を追加します助けに。しかしprogは、parserから来る唯一のものです。

positional arguments: 
    META  prog: custom, dest=foo, nargs=None, type=int, default=default 
関連する問題