Argparse: обязательные аргументы, перечисленные в разделе "необязательные аргументы"?


Я использую следующий простой код для разбора некоторых аргументов; обратите внимание, что один из них требуется. К сожалению, когда пользователь запускает скрипт без предоставления аргумента, отображаемый текст usage/help не указывает на то, что есть необязательный аргумент, который я нахожу очень запутанным. Как я могу заставить python указать, что аргумент не является необязательным?

вот код:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

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

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name
3 124

3 ответа:

параметров, начинающийся с - или -- обычно считаются необязательными. Все остальные параметры являются позиционными параметрами и как таковые требуются по дизайну (например, аргументы позиционной функции). Можно потребовать дополнительные аргументы, но это немного против их дизайна. Поскольку они все еще являются частью непозиционных аргументов, они все равно будут перечислены под запутанным заголовком "необязательные аргументы", даже если они необходимы. Отсутствующие квадратные скобки в части использования однако покажите, что они действительно необходимы.

см. также документация:

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

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

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

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name

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

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg')
    optional.add_argument('--optional_arg')
    return parser.parse_args()

и это выводит:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

Я могу жить без 'помощи' в группы дополнительного аргументов.

строительство от @Karl Rosaen

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg')
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

и это выводит:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

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