Когда используется argparse, он обеспечивает автоматическую обработку команд -h/--help. Даже если были добавлены подпарсеры, он обрабатывает их справку по подпарсерам, а также глобальную справку, которая предоставляет список этих подпарсеров.

Все идет нормально.

Добавление команды справки

Добавление команды helpcommand является любезностью по отношению к пользователю, если используются субпарсеры. Рекомендуется предоставить пользователю два способа просмотра справки: program subcommand --help и program help subcommand.

К сожалению, argparse не предоставляет такой роскоши. Это следует делать самому.

Анализ проблемы

  1. Добавьте команду help. Тривиально, просто добавьте еще один подпарсер.
  2. Найти данный подпарсер из другого подпарсера и найти все подпарсеры
  3. Узнайте, как распечатать справку для данного подпарсера

Доступные данные и область действия: мы вызываем 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()