web-dev-qa-db-ja.com

Python argparse-複数のサブパーサーに引数を追加する

私のスクリプトでは、1つのメインパーサーと複数のサブパーサーを定義しています。 _-p_引数をいくつかのサブパーサーに適用したい。これまでのところ、コードは次のようになります。

_parser = argparse.ArgumentParser(prog="myProg")
subparsers = parser.add_subparsers(title="actions")

parser.add_argument("-v", "--verbose",
                    action="store_true",
                    dest="VERBOSE",
                    help="run in verbose mode")

parser_create = subparsers.add_parser ("create", 
                                        help = "create the orbix environment")
parser_create.add_argument ("-p", 
                            type = int, 
                            required = True, 
                            help = "set db parameter")

# Update
parser_update = subparsers.add_parser ("update", 
                                        help = "update the orbix environment")
parser_update.add_argument ("-p", 
                            type = int, 
                            required = True, 
                            help = "set db parameter")
_

ご覧のとおり、add_arument ("-p")が2回繰り返されています。私は実際にはもっと多くのサブパーサーを持っています。繰り返しを避けるために、既存のサブパーサーをループする方法はありますか?

記録のために、Python 2.7

57
rahmu

これは、共通オプションを含む 親パーサー を定義することで実現できます。

import argparse

parent_parser = argparse.ArgumentParser(description="The parent parser")
parent_parser.add_argument("-p", type=int, required=True,
                           help="set db parameter")
subparsers = parent_parser.add_subparsers(title="actions")
parser_create = subparsers.add_parser("create", parents=[parent_parser],
                                      add_help=False,
                                      description="The create parser",
                                      help="create the orbix environment")
parser_create.add_argument("--name", help="name of the environment")
parser_update = subparsers.add_parser("update", parents=[parent_parser],
                                      add_help=False,
                                      description="The update parser",
                                      help="update the orbix environment")

これにより、次の形式のヘルプメッセージが生成されます。

parent_parser.print_help()

出力:

usage: main.py [-h] -p P {create,update} ...
The parent parser
optional arguments:
  -h, --help       show this help message and exit
  -p P             set db parameter
actions:
  {create,update}
    create         create the orbix environment
    update         update the orbix environment
parser_create.print_help()

出力:

usage: main.py create [-h] -p P [--name NAME] {create,update} ...
The create parser
optional arguments:
  -h, --help       show this help message and exit
  -p P             set db parameter
  --name NAME      name of the environment
actions:
  {create,update}
    create         create the orbix environment
    update         update the orbix environment

ただし、プログラムを実行する場合、アクション(createまたはupdate)を指定しなくてもエラーは発生しません。この動作が必要な場合は、次のようにコードを変更します。

<...>
subparsers = parent_parser.add_subparsers(title="actions")
subparsers.required = True
subparsers.dest = 'command'
<...>

この修正は this SO question で提起されました。これはプルリクエストを追跡する問題を指します。

74
Sven Marnach

サブパーサーをループして、すべてのサブパーサーに同じオプションを追加することもできます。

parser = argparse.ArgumentParser(prog="myProg")
subparsers = parser.add_subparsers(title="actions")
parser.add_argument("-v", "--verbose",
                    action="store_true",
                    dest="VERBOSE",
                    help="run in verbose mode")

parser_create = subparsers.add_parser ("create", 
                                        help = "create the orbix environment")
parser_update = subparsers.add_parser ("update", 
                                        help = "update the orbix environment")

for subparser in [parser_create, parser_update]:
    subparser.add_argument ("-p", 
                            type = int, 
                            required = True, 
                            help = "set db parameter")
7
JanK

次の方法でサブパーサーをループできます。

for name, subp in subparsers.choices.items():
    print(subp)
    subp.add_argument(dest='g', help='Input for g variable', default=7, type=int)

subparsers.choicesを使用すると、すべてのサブパーサーをハードコーディングする必要がなくなります。

4
Gerard Kool