Экран справки Argparse: показать обязательные аргументы над необязательными аргументами для SUB-парсеров - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь получить экран справки подпарсеров , чтобы показать обязательные аргументы ВЫШЕ (перед) необязательные аргументы.

Я следовалпоследний ответ на Argparse: Обязательные аргументы, перечисленные в разделе «необязательные аргументы»? , но не удалось получить требуемые аргументы для отображения над необязательными аргументами.

Вот мой фрагмент кода:

## using Python 3.6.3
import argparse
from argparse import RawTextHelpFormatter

main_parser = argparse.ArgumentParser(prog="myProg")
subparsers = main_parser.add_subparsers()

## common to all sub-parsers
common_parser = argparse.ArgumentParser(add_help=False)
common_parser.add_argument('foo')

optional = common_parser._action_groups.pop()
required = common_parser.add_argument_group('required arguments')
required.add_argument("-p", type=int, required=True, help='help for -p')
optional.add_argument('-x', help='help for -x')
common_parser._action_groups.append(optional) 

abcd_parser = subparsers.add_parser("abcd", parents=[common_parser])
wxyz_parser = subparsers.add_parser("wxyz", parents=[common_parser])

args = main_parser.parse_args()

Вывод:

$ ./myProg abcd -h
usage: myProg abcd [-h] -p P [-x X] foo

positional arguments:
  foo

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

required arguments:
  -p P        help for -p

Однако я хотел бы, чтобы вывод выглядел следующим образом:

$ ./myProg abcd -h
usage: myProg abcd [-h] -p P [-x X] foo

positional arguments:
  foo

required arguments:
  -p P        help for -p

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

Возможно ли получить желаемые результаты?Что нужно сделать?

Спасибо

- Андрей

1 Ответ

0 голосов
/ 11 октября 2018

Это не уникально для подпарсеров.Добавленные группы всегда перечисляются после групп по умолчанию.

In [2]: parser = argparse.ArgumentParser()

Справка создается методом format_help:

In [3]: parser.format_help??
Signature: parser.format_help()
Docstring: <no docstring>
Source:   
    def format_help(self):
        formatter = self._get_formatter()

        # usage
        formatter.add_usage(self.usage, self._actions,
                            self._mutually_exclusive_groups)

        # description
        formatter.add_text(self.description)

        # positionals, optionals and user-defined groups
        for action_group in self._action_groups:
            formatter.start_section(action_group.title)
            formatter.add_text(action_group.description)
            formatter.add_arguments(action_group._group_actions)
            formatter.end_section()

        # epilog
        formatter.add_text(self.epilog)

        # determine help from format above
        return formatter.format_help()

Она проходит по _action_groups и добавляет каждуюк объекту форматирования.

Для недавно инициированного синтаксического анализатора есть 2 группы:

In [4]: parser._action_groups
Out[4]: 
[<argparse._ArgumentGroup at 0x7f4dfc2a22e8>,
 <argparse._ArgumentGroup at 0x7f4dfc2a2400>]
In [5]: [g.title for g in parser._action_groups]
Out[5]: ['positional arguments', 'optional arguments']

Действие help также было добавлено в группу 'необязательных аргументов'. ​​

Добавьте группу, и список теперь:

In [6]: g1 = parser.add_argument_group('required arguments')
In [7]: [g.title for g in parser._action_groups]
Out[7]: ['positional arguments', 'optional arguments', 'required arguments']

Итак:

In [8]: parser.add_argument('foo');
In [9]: parser.add_argument('--bar');
In [10]: g1.add_argument('--baz',required=True);
In [11]: parser.print_help()
usage: ipython3 [-h] [--bar BAR] --baz BAZ foo

positional arguments:
  foo

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

required arguments:
  --baz BAZ

Изменение порядка требует либо изменения метода format_help, либо (возможно)изменив порядок элементов в списке _action_groups.

Например, мы могли бы обратить этот список в обратном направлении. IN_PLACE:

In [18]: parser._action_groups.reverse()
In [19]: [g.title for g in parser._action_groups]
Out[19]: ['required arguments', 'optional arguments', 'positional arguments']
In [20]: parser.print_help()
usage: ipython3 [-h] [--bar BAR] --baz BAZ foo

required arguments:
  --baz BAZ

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

positional arguments:
  foo

Пользовательское переупорядочение, подобное этому, тоже работает нормально:

In [22]: alist = parser._action_groups
In [23]: alist[:] = [alist[0], alist[2], alist[1]]

Нет гарантий.Я просто изучаю варианты, основанные на моих знаниях кода.

...