Когда используется argparse, он обеспечивает автоматическую обработку команд -h
/--help
. Даже если были добавлены подпарсеры, он обрабатывает их справку по подпарсерам, а также глобальную справку, которая предоставляет список этих подпарсеров.
Все идет нормально.
Добавление команды справки
Добавление команды help
command является любезностью по отношению к пользователю, если используются субпарсеры. Рекомендуется предоставить пользователю два способа просмотра справки: program subcommand --help
и program help subcommand
.
К сожалению, argparse не предоставляет такой роскоши. Это следует делать самому.
Анализ проблемы
- Добавьте команду
help
. Тривиально, просто добавьте еще один подпарсер. - Найти данный подпарсер из другого подпарсера и найти все подпарсеры
- Узнайте, как распечатать справку для данного подпарсера
Доступные данные и область действия: мы вызываем command
подпарсера (рекомендуется использовать subparser.set_defaults(command=myfunc)
; у нас есть доступ только к подпарсеру, но не к самому ArgumentParser()
. Такое часто случается, когда вы разделяете команды на автономные классы с помощью следующего кода:
subparsers = self.parser.add_subparsers(title=’commands’) FirstCommand(subparsers) SecondCommand(subparsers)
и каждая команда добавляет собственные параметры, например:
class GenericCommand(object): def __init__(self, subparsers): self.parser = subparsers.add_parser(self.name, help=self.help) self.parser.add_argument(...) ...subparsers.set_defaults(command=self.command)
def command(self, args): ....
Поиск подпарсеров
Это довольно разочаровывает, но оба dict(subparsers)
и list(subparsers)
не работают. Документация не проясняет внутренности argparse, поэтому я использовал самоанализ, чтобы заглянуть внутрь.
Я обнаружил, что subparsers
имеет атрибут .choices
, который содержит все доступные подпарсеры как OrderedDict
. Доступ к нему можно получить с помощью ключа, можно выполнить итерацию по ключам или значениям. Все, что нам нужно.
Справочное сообщение
Каждый подпарсер или содержимое choices
имеет функцию print_help()
, которая делает все, как вы ожидаете.
Результирующий код
class HelpCommand(object): def __init__(self, subparsers): self.parser = subparsers.add_parser( 'help', help='display help' ) self.parser.add_argument( 'name', nargs='?', help='Command to show help for' ) self.subparsers = subparser self.parser.set_defaults(command=self.command) def command(self, args): if args.name: self.subparsers.choices[args.name].print_help() else: print("Use help [name] to show help for given command") print("List of available commands:") print("\n".join(list(self.subparsers.choices.iterkeys()))) parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title='commands') FirstCommand(subparsers) SecondCommand(subparsers) HelpCommand(subparsers) args = parser.parse_args() args.command()