2016-11-21 5 views
3

私はargparseを使用しています。私は独自のオプションを持つさまざまなグループを持っています。argparseのグループ間でヘルプをカスタマイズ

ここで--helpオプションを使用すると、デフォルトですべてのオプションを表示する必要はありません。 --helpには、一連のグループオプションのみが表示されます。

他のグループオプションは--help_2--help_1として、他のヘルプオプションに基づいて表示される必要があります。たとえば

--help' to show Group 2 and 3 
--help_1' to show Group 11 and 12 
--help_2' to show Group 22 and 23 

私たちはを使用して、デフォルトの--helpオプションを無効にすることができることを知っていますadd_help = Falseしかし、選択したグループ固有のヘルプのみを表示するにはどうしたらいいですか?

我々は_action_groups属性を使用して、パーサーからグループのリストを取得することができますが、それらは以下のような任意のprint_help()オプションが公開されていません。

マイサンプルコード:

parser = argparse.ArgumentParser(add_help=False) 

parser.add_argument('--help_a', action='store_true') 
parser.add_argument('--help_b', action='store_true') 

group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 

# TODO: --help_a to only print "Feature 1" groups help 
# and --help_b to print Feature 2 and 3's help. 

EDIT:上記を解決するsubparserを使用し、(代わりにグループの)パーサを加えます。しかし、サブパーザーは私の場合には適合しません。私はそれを常に解析しているので、表示するにはヘルプをカスタマイズする必要があります。

+0

なぜ「less」を通さないのですか? 'python command.py --help | less' –

+0

それは私の場合にはそう思わない。私は自分のAPIやスクリプトを使って外部のユーザーが自分の側で解析することを望んでいません。スクリプトはそれを単独で処理する必要があります。 – baky

+0

私は分かりません。どのグループを使用しているのかと、別のヘルプページを表示する理由をさらにいくつか追加できますか? –

答えて

1

ここでカスタムformat_helpアプローチですされています

import argparse 

def format_help(self, groups=None): 
    # self == parser 
    formatter = self._get_formatter() 

    # usage 
    formatter.add_usage(self.usage, self._actions, 
         self._mutually_exclusive_groups) 

    # description 
    formatter.add_text(self.description) 

    if groups is None: 
     groups = self._action_groups 

    # positionals, optionals and user-defined groups 
    for action_group in groups: 
     formatter.start_section(action_group.title) 
     formatter.add_text(action_group.description) 
     formatter.add_arguments(action_group._group_actions) 
     formatter.end_section() 

    # epilog 
    formatter.add_text(self.epilog) 

    # determine help from format above 
    return formatter.format_help() 

<your parser> 

args = parser.parse_args() 
# _action_groups[:2] are the default ones 
if args.help_a: 
    print(format_help(parser, [parser._action_groups[2]])) 
    parser.exit() 
if args.help_b: 
    print(format_help(parser, parser._action_groups[3:])) 
    parser.exit() 

サンプル

1444:~/mypy$ python stack40718566.py --help_a 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 1: 
    --foo1 FOO1 

1444:~/mypy$ python stack40718566.py --help_b 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 2: 
    --foo2 FOO2 

Feature 3: 
    --foo3 FOO3 

だから、単にデフォルトのようなものだが実行されますformat_help、それ以外の場合はgroupsパラメータ。 ArgumentParserサブクラスのデフォルトメソッドを置き換えることさえできます。

標準のヘルプと同じように動作するカスタムクラスを作成することもできますが、いくつかの種類のgroup_listパラメータが必要です。しかし、この構文解析後のアクションは、コードとテストが簡単です。

+0

ありがとう、私も同様の行を考えていた、 'help_bucket'として、余分なパラメータを取る_ActionGroupクラス自体をオーバーライドすると、使用するのを助ける意味。しかし、これはトリックを行い、クリーナーで簡単です。ただし、使用法はデフォルトですべてのオプションを表示しますが、これはadd_usageに必要なアクションだけを追加することで簡単に解決できます。再度、感謝します – baky

0

あなたがしようとしていることに対してお勧めします。

You are solving a problem that isn't yours to solve.使用状況を返すのはスクリプトの仕事です。それがたくさんのテキストであれば、あなたの問題ではありません。あなたができることは、あなたがやっていることです:ユーザにとって意味のあるグループに引数を入れてください。しかし、テキストの量はであり、データ構造の問題ではなく、データプレゼンテーションの問題です。

第2に、を使用していない大会に従うことになります。通常はあります

man command 
command --help 
command subcommand --help 

初めてのユーザーには他のものが混乱することがあります。

また、引数グループが多い場合は、--help_*を次に参照する必要があるかどうかを調べるには、常に--helpに問い合わせる必要があります。 すぐに--helpにそれを提示することができたとき、これはユーザーにをイライラすることができます。

複数のヘルプページを使用する場合、はヘルプテキストの再利用を防ぎます。複数のページを手動で切り替えることなく検索することはできません。

を行う正しい方法は、lessのようなページネージャーを通したテキストです。これは、ユーザーが、ページでテキストページを読んで、それを検索(プレス/)またはファイルに保存することができます:output is an interactive terminalautomatically pass the output through less場合

command --help | less 

便宜上git logのようないくつかのコマンドは、もご確認ください。これは

command --help > help.txt 

を意味するだろう

command --help 

は、ヘルプページネーション内のテキスト、および検索可能を示しているが、ファイルに助けを節約できます。

ように、WindowsとUNIXの両方であなたのための私の推薦は

import os 
import sys 
import argparse 
import subprocess 


def less(data): 
    if sys.stdout.isatty(): 
     if os.name == 'posix': 
      cmd = "less" 
     elif os.name == 'nt': 
      cmd = "more" 

     process = subprocess.Popen([cmd], stdin=subprocess.PIPE) 

     try: 
      process.stdin.write(data) 
      process.communicate() 
     except IOError: 
      pass 
    else: 
     print data 


class MyArgumentParser(argparse.ArgumentParser): 
    def print_help(self, file=None): 
     less(self.format_help()) 
     self.exit() 


parser = MyArgumentParser(prog='PROG') 
group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 
# parse some argument lists 
print parser.parse_args() 
+0

詳細な回答ありがとうございます。人々がどのヘルプを使用するのかを調べることができないという上記のコメントに関して、私は 'help_all'オプションを追加していますので、これは問題ではありません。ところで、私の質問に似た何かが可能ならば、私はまだ見ていきます。 – baky

+0

@hpauljは同じ解決策を投稿しました。してください見てください – baky

関連する問題