Argparse python, удалите список подпарантов в меню справки - программирование
Подтвердить что ты не робот

Argparse python, удалите список подпарантов в меню справки

Я пишу утилиту командной строки, используя Argparse, и добавил кучу sub_parsers (подкоманды). В меню справки они отображаются под группой "команды", и я получаю список всех возможных вариантов. Однако до появления этого списка все одинаковые команды отображаются под заголовком группы в фигурных скобках:

Commands:
    {foo, bar}

    foo          - foo does foo
    bar          - bar does bar

Я хочу удалить лишние записи, которые появляются в фигурных скобках. Он появляется только в этой группе, заполненной sub_parsers.

Мой код для обработки выглядит так: (где parser является экземпляром ArgumentParser())

subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

Я просмотрел атрибуты и методы моей группы действий команд и не могу найти ничего, что разрешит это для меня (по крайней мере, из того, что я могу понять). Я не уверен, что кто-то еще справился с этим, я понимаю, что это, вероятно, немного неясно. И снова все, что я пытаюсь сделать, это найти способ удалить избыточный список команд, которые появляются в фигурных скобках.

4b9b3361

Ответ 1

Часть "{foo, bar}" является аргументом "metavar". Метаваром является то, как argparse ссылается на ожидаемые значения аргументов в строках использования и помощи. argparse рассматривает подкоманды как аргумент с несколькими вариантами выбора, поэтому, если вы не укажете метавару, по умолчанию это список вариантов (подкоманд) в фигурных скобках. Он позволяет пользователю узнать возможные варианты для подкоманд, но поскольку они перечислены ниже, это избыточно, и если у вас много подкоманд, это уродливо.

Вы можете легко заменить своим выбранным метаваром:

subparsers = parser.add_subparsers(title="Commands", metavar="<command>")

Ответ 2

Вы можете настроить форматирование сообщений справки, написав свой собственный класс форматирования, основываясь на интерфейсе argparse.HelpFormatter и передав его конструктору парсера, используя аргумент formatter_class.

Подробнее см. http://docs.python.org/dev/library/argparse.html#formatter-class

Ответ 3

После глубокого погружения в исходный код argparse я создал хак для удаления избыточного списка выбора {cmd1,...}.

Hack реализует настраиваемый формуляр справки, который модифицирует методы форматирования HelpFormatter при работе с подпарамеры действия. В частности, он удаляет подпарамеры metavar и help строка в группе аргументов подкоманды и удаляет дополнительный отступ этих подкоманд.

Пожалуйста, используйте с осторожностью.

Версия python 3, протестированная с помощью python3.6

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction

class NoSubparsersMetavarFormatter(HelpFormatter):

    def _format_action(self, action):
        result = super()._format_action(action)
        if isinstance(action, _SubParsersAction):
            # fix indentation on first line
            return "%*s%s" % (self._current_indent, "", result.lstrip())
        return result

    def _format_action_invocation(self, action):
        if isinstance(action, _SubParsersAction):
            # remove metavar and help line
            return ""
        return super()._format_action_invocation(action)

    def _iter_indented_subactions(self, action):
        if isinstance(action, _SubParsersAction):
            try:
                get_subactions = action._get_subactions
            except AttributeError:
                pass
            else:
                # remove indentation
                yield from get_subactions()
        else:
            yield from super()._iter_indented_subactions(action)

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter)
subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

parser.parse_args(['-h'])

Версия python 2, протестированная с помощью python2.7

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction

class NoSubparsersMetavarFormatter(HelpFormatter):

    def _format_action(self, action):
        result = super(NoSubparsersMetavarFormatter,
                       self)._format_action(action)
        if isinstance(action, _SubParsersAction):
            return "%*s%s" % (self._current_indent, "", result.lstrip())
        return result

    def _format_action_invocation(self, action):
        if isinstance(action, _SubParsersAction):
            return ""
        return super(NoSubparsersMetavarFormatter,
                     self)._format_action_invocation(action)

    def _iter_indented_subactions(self, action):
        if isinstance(action, _SubParsersAction):
            try:
                get_subactions = action._get_subactions
            except AttributeError:
                pass
            else:
                for subaction in get_subactions():
                    yield subaction
        else:
            for subaction in super(NoSubparsersMetavarFormatter,
                                   self)._iter_indented_subactions(action):
                yield subaction

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter)
subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

parser.parse_args(['-h'])

Пример вывода:

usage: a.py [-h] {foo,bar} ...

optional arguments:
  -h, --help  show this help message and exit

Commands:
  foo         - foo does foo
  bar         - bar does bar