Аргумент Python: nargs='?' и необязательные аргументы

Допустим, у меня есть простая программа под названием readfile.py, которая поддерживает аргументы командной строки, используя Python argparse.

Программа читает из файла, указанного позиционным аргументом input. Без указания дополнительных аргументов эта программа не очень увлекательна. Он просто читает из input и завершает работу. Необязательный аргумент --output [OUTPUT_FILE] означает, что входной файл должен быть записан в файл. OUTPUT_FILE также является необязательным. Если он не указан, ввод должен быть записан в default.out.

Я настроил свой парсер аргументов следующим образом:

parser = argparse.ArgumentParser(description='Read from a file')
parser.add_argument(
    'input',
    help='file to read from')
parser.add_argument(
    '--output',
    nargs='?',
    const='default.out',
    default=None,
    help="""write file to %(metavar)s. If %(metavar)s isn't
         specified, write file to %(const)s.""",
    metavar='OUTPUT_FILE')
args = parser.parse_args()
return args.file, args.output_file

Примечание. Я использую default=None, так что если --ouput не отображается в командной строке, я могу обнаружить его отсутствие с помощью None.

Что дает сигнатуру использования, подобную этой:

usage: readfile.py [-h] [--output [OUTPUT_FILE]] input

Это обрабатывает аргументы, как и ожидалось, если я запускаю

python readfile.py input.in --output somefile.out

or

python readfile.py --output somefile.out input

Он устанавливает output в default.out, если я запускаю

python readfile.py input.in --output

но если я побегу

python readfile.py --output input.in

он жалуется на то, что аргументов слишком мало. Я думал, что argparse будет достаточно «умным», чтобы интерпретировать этот шаблон, установив input в input.in и output в default.out. Сгенерированное использование даже предполагает это.

Я что-то упускаю?


person eidorb    schedule 14.12.2012    source источник
comment
Тот, кто проголосовал против этого вопроса, должен хотя бы оставить конструктивный намек в комментарии.   -  person cfi    schedule 23.03.2013


Ответы (2)


Нет, это не распознается. В последнем примере вы явно передаете input.in в --output.

Я бы порекомендовал вам поменять местами параметры default и const. Вы хотите, чтобы значение по умолчанию было default.out, поэтому оно должно быть default='default.out'. Затем const можно установить на что-то другое в случае наличия пустого параметра --output.

Таким образом, вам не нужно добавлять параметр --output, если только вы не хотите изменить значение по умолчанию, и вы можете использовать пустой параметр --output, если хотите, например, вывести stdout.

person Lennart Regebro    schedule 14.12.2012
comment
В этом случае (сбивает с толку?) default не используется для обозначения отсутствия параметра после --output, а const используется для полного отсутствия параметра --output. - person eidorb; 14.12.2012
comment
@eidorb: Да, и это наоборот. Измените его вокруг. Используйте его так, как он должен использоваться. - person Lennart Regebro; 14.12.2012
comment
Я должен извиниться. В моем комментарии это наоборот, но в моем коде все так, как я задумал. - person eidorb; 15.12.2012
comment
@eidorb: И это наоборот. Измените его вокруг. Используйте его так, как он должен использоваться. Шутки в сторону. - person Lennart Regebro; 15.12.2012

Вы можете передать «--», чтобы отметить конец любых опций. Например:

python readfile.py --output -- input

имеет намеченный эффект. Однако, делая аргумент --output обязательным и разрешая:

python readfile.py --output - input

наверное чище.

person cagney    schedule 31.07.2015