Подтвердить что ты не робот

Python argparse - добавление аргумента в несколько подпараметров

Мой script определяет один основной синтаксический анализатор и несколько подпараметров. Я хочу применить аргумент -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") повторяется дважды. У меня на самом деле намного больше подпанелей. Есть ли способ перебрать существующие подпарамеры во избежание повторения?

Для записи я использую Python 2.7

4b9b3361

Ответ 1

Это может быть достигнуто путем определения родительского парсера, содержащего общие параметры:

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'
<...>

Это исправление было затронуто в этом вопросе SO, касающемся проблемы отслеживания запроса на удаление.

Ответ 2

Вы также можете перебрать подпаранты и добавить к ним все те же параметры.

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")

Ответ 3

Вы можете зациклить ваши подпарсеры следующим образом.

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

принятый ответ правильный; правильный способ - использовать родительские парсеры. Однако пример кода IMO на самом деле не решил проблему. Позвольте мне добавить свои несколько центов, чтобы привести более подходящий пример.

Основное отличие от принятого ответа заключается в явной возможности иметь некоторые аргументы корневого уровня (например, --verbose), а также общие аргументы только для некоторых подпарасеров (-p только для подпапок create и update, но не для другие)

# Same main parser as usual
parser = argparse.ArgumentParser()

# Usual arguments which are applicable for the whole script / top-level args
parser.add_argument('--verbose', help='Common top-level parameter',
                    action='store_true', required=False)

# Same subparsers as usual
subparsers = parser.add_subparsers(help='Desired action to perform', dest='action')

# Usual subparsers not using common options
parser_other = subparsers.add_parser("extra-action", help='Do something without db')

# Create parent subparser. Note 'add_help=False' and creation via 'argparse.'
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-p', help='add db parameter', required=True)

# Subparsers based on parent

parser_create = subparsers.add_parser("create", parents=[parent_parser],
                                      help='Create something')
# Add some arguments exclusively for parser_create

parser_update = subparsers.add_parser("update", parents=[parent_parser],
                                      help='Update something')
# Add some arguments exclusively for parser_update 

Это справочное сообщение верхнего уровня (обратите внимание, что здесь не показан параметр -p, а это именно то, чего вы ожидаете &— оно характерно для некоторых подпапсеров):

>>> parser.print_help()
usage: [-h] [--verbose] {extra-action,create,update} ...

positional arguments:
  {extra-action,create,update}
                        Desired action to perform
    extra-action        Do something without db
    create              Create something
    update              Update something

optional arguments:
  -h, --help            show this help message and exit
  --verbose             Common top-level parameter

И справочное сообщение для действия create:

>>> parser_create.print_help()
usage:  create [-h] -p P

optional arguments:
  -h, --help  show this help message and exit
  -p P        add db parameter