Сообщить об ошибке.

Метод add_subparsers() объекта ArgumentParser в Python

Создание подкоманд командной строки и парсера их параметров

Синтаксис:

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers([title][, description][, prog]
                                  [, parser_class][, action]
                                  [, option_string][, dest][, required]
                                  [, help][, metavar])

parser_a = subparsers.add_parser([help])
parser_a.add_argument(...)
...

Параметры:

  • title - заголовок для группы суб-парсера в выводе справки. По умолчанию "subcommands" если есть описание, в противном случае используется заголовок для позиционных параметров,
  • description - описание для группы суб-парсера в выводе справки, по умолчанию None,
  • prog - информация об использовании, которая будет отображаться со справкой по подкоманде, по умолчанию это имя программы и любые позиционные параметры.
  • parser_class - класс, который будет использоваться для создания экземпляров суб-парсера, по умолчанию класс текущего парсера (например ArgumentParser),
  • action - основной тип действия, выполняемого при обнаружении этого параметра в командной строке (поведение такое же как в add_argument()),
  • dest - имя атрибута, под которым будет храниться имя подкоманды. По умолчанию None и значение не сохраняется (поведение такое же как в add_argument()),
  • required - должна ли быть предоставлена ​​подкоманда, по умолчанию False (добавлено в Python 3.7) (поведение такое же как в add_argument()),
  • help - cправка для суб-парсера в выводе справки, по умолчанию None (поведение такое же как в add_argument()),
  • metavar - строка, представляющая доступные подкоманды в справке; по умолчанию это None и представляет подкоманды в форме {cmd1, cmd2, ..} (поведение такое же как в add_argument()),

Возвращаемое значение:

  • специальный action object.

Описание:

Многие программы разделяют свои функции на несколько подкоманд, например, система управления версиями svn может вызывать подкоманды, такие как svn checkout, svn update и svn commit. Такое разделение функциональности может быть особенно хорошей идеей, когда программа выполняет несколько различных функций, требующих разных типов аргументов командной строки.

Объект ArgumentParser поддерживает создание таких подкоманд с помощью метода parser.add_subparsers(). Метод parser.add_subparsers() обычно вызывается без аргументов и возвращает специальный объект action object. У этого объекта есть единственный метод subparsers.add_parser(), который принимает имя команды и любые аргументы конструктора ArgumentParser и возвращает объект ArgumentParser, который можно изменять как обычно.

Примеры использования:

>>> # создать парсер верхнего уровня
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', action='store_true', help='foo help')
>>> subparsers = parser.add_subparsers(help='sub-command help')

>>> # создать парсер для подкоманды 'a'
>>> parser_a = subparsers.add_parser('a', help='a help')
>>> parser_a.add_argument('bar', type=int, help='bar help')

>>> # Создать парсер для подкоманды 'b'
>>> parser_b = subparsers.add_parser('b', help='b help')
>>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')

>>> # анализируем списки параметров командной строки
>>> parser.parse_args(['a', '12'])
# Namespace(bar=12, foo=False)
>>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
# Namespace(baz='Z', foo=True)

Обратите внимание, что объект, возвращаемый методом parser.parse_args(), будет содержать только атрибуты основного синтаксического анализатора и параметры подкоманды, указанной в командной строкой (а не каких-либо других субпараметров). Таким образом, в приведенном выше примере, когда указана подкоманда a, то присутствуют только атрибуты foo и bar, а когда указана подкоманда b, то присутствуют только атрибуты foo и baz.

Когда справка запрашивается у суб-парсера, то будет напечатана только справка для этого конкретного парсера. Справочное сообщение не будет включать сообщения родительского или родственного анализатора.

Справочное сообщение для каждой подкоманды, может быть предоставлено путем передачи аргумента help в метод subparsers.add_parser(), как указано выше в примере.

>>> parser.parse_args(['--help'])
# usage: PROG [-h] [--foo] {a,b} ...
# 
# positional arguments:
#   {a,b}   sub-command help
#     a     a help
#     b     b help
# 
# optional arguments:
#   -h, --help  show this help message and exit
#   --foo   foo help

>>> parser.parse_args(['a', '--help'])
# usage: PROG a [-h] bar
# 
# positional arguments:
#   bar     bar help
# 
# optional arguments:
#   -h, --help  show this help message and exit
 
>>> parser.parse_args(['b', '--help'])
# usage: PROG b [-h] [--baz {X,Y,Z}]
# 
# optional arguments:
#   -h, --help     show this help message and exit
#   --baz {X,Y,Z}  baz help

Метод add_subparsers() также поддерживает ключевые аргументы title и description. Если любой из них присутствует, то команды суб-парсера появятся в отдельной группе в выводе справки. Например:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',
...                                    description='valid subcommands',
...                                    help='additional help')
>>> subparsers.add_parser('foo')
>>> subparsers.add_parser('bar')
>>> parser.parse_args(['-h'])
# usage:  [-h] {foo,bar} ...
# 
# optional arguments:
#   -h, --help  show this help message and exit
# 
# subcommands:
#   valid subcommands
#  
#   {foo,bar}   additional help

Кроме того, add_parser() поддерживает дополнительный аргумент псевдонимов aliases, который позволяет нескольким строкам ссылаться на один и тот же суб-парсер. В этом примере, псевдоним co являются сокращением для подкоманды checkout:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>> checkout = subparsers.add_parser('checkout', aliases=['co'])
>>> checkout.add_argument('foo')
>>> parser.parse_args(['co', 'bar'])
# Namespace(foo='bar')

Один особенно эффективный способ обработки подкоманд - объединить использование метода add_subparsers() с вызовами методов set_defaults(), чтобы каждый суб-парсер знал, какую функцию Python он должен выполнить. Например:

>>> # sub-command functions
>>> def foo(args):
...     print(args.x * args.y)
...
>>> def bar(args):
...     print(f'(({args.z}))')
...
>>> # парсер верхнего уровня
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()

>>> # парсер для подкоманды 'foo'
>>> parser_foo = subparsers.add_parser('foo')
>>> parser_foo.add_argument('-x', type=int, default=1)
>>> parser_foo.add_argument('y', type=float)
>>> parser_foo.set_defaults(func=foo)

>>> # парсер для подкоманды 'bar'
>>> parser_bar = subparsers.add_parser('bar')
>>> parser_bar.add_argument('z')
>>> parser_bar.set_defaults(func=bar)

>>> # анализируем параметры и вызываем функцию
>>> args = parser.parse_args('foo 1 -x 2'.split())
>>> args.func(args)
# 2.0

>>> # анализируем параметры и вызываем функцию
>>> args = parser.parse_args('bar XYZYX'.split())
>>> args.func(args)
# ((XYZYX))

Таким образом, можно позволить методу parser.parse_args() выполнить работу по вызову соответствующей функции после завершения анализа аргументов. Связывание функций с такими действиями, как правило, является самым простым способом обработки различных действий для каждой подкоманды и ее параметров.

Если необходимо проверить имя вызванного суб-парсера, то будет работать ключевой аргумент dest для вызова parser.add_subparsers():

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(dest='subparser_name')
>>> subparser1 = subparsers.add_parser('1')
>>> subparser1.add_argument('-x')
>>> subparser2 = subparsers.add_parser('2')
>>> subparser2.add_argument('y')
>>> parser.parse_args(['2', 'frobble'])
# Namespace(subparser_name='2', y='frobble')