как сделать аргумент необязательным в python argparse
Я хотел бы, чтобы эти заклинания myprog работали, и никаких других.
$ python3 myprog.py -i infile -o outfile
$ python3 myprog.py -o outfile
$ python3 myprog.py -o
$ python3 myprog.py
в частности, я хочу сделать незаконным указание infile, но не outfile.
в третьем случае предполагается имя outfile по умолчанию: "out.формат JSON."Во втором, третьем и четвертом случаях предполагается имя входного файла по умолчанию," file.n.json", где n-целочисленный номер версии. В четвертом случае выходной файл будет файл".n+1.json", где n+1 - версия номер один больше, чем версия входного файла. Соответствующий раздел моего кода:
import argparse
parser = argparse.ArgumentParser(description="first python version")
parser.add_argument('-i', '--infile', nargs=1, type=argparse.FileType('r'), help='input file, in JSON format')
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')
args = parser.parse_args()
print("Here's what we saw on the command line: ")
print("args.infile",args.infile)
print("args.outfile",args.outfile)
if args.infile and not args.outfile:
parser.error("dont specify an infile without specifying an outfile")
elif not args.infile:
print("fetching infile")
else: # neither was specified on the command line
print("fetching both infile and outfile")
проблема в том, когда я бегу
$ python3 myprog.py -i infile.json
вместо ошибки парсера, на которую я надеялся, я получаю:
Here's what we saw on the command line:
args.infile [<_io.TextIOWrapper name='infile.json' mode='r' encoding='UTF-8'>]
args.outfile <_io.TextIOWrapper name='out.json' mode='w' encoding='UTF-8'>
fetching both infile and outfile
...это говорит о том, что, хотя в командной строке не было "-o", она действовала так, как будто была.
2 ответов
вы указали аргумент по умолчанию для outfile.
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')
если -o
опция не указана в командной строке, парсер arg вставляет аргумент по умолчанию.
заменить на:
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), help='output file, in JSON format')
и все должно работать, как вы ожидаете.
если вы хотите иметь возможность указать -o
, без имени, вы, вероятно, хотите что-то вроде:
out_file = args.out if args.out is not None else 'json.out'
Я не уверен, что соответствующий параметр None
или ''
(т. е. пустая строка), если указать -o
без параметра--я подозреваю, что это None
, но я точно не знаю. Вы должны проверить это, чтобы быть уверенным.
Я не знаю, как это сделать без дополнительной логики с argparse.
в качестве дополнения к выбранному ответ:
возможность работать -o
без указания файла, можно сделать с помощью const
в сочетании с nargs='?'
.
документы:
когда add_argument () вызывается со строками опций (например,- f или --foo) и nargs='?'. Это создает необязательный аргумент, который можно использовать по нулю или одному аргументу командной строки. При разборе командной строки, если строка параметра встречается с no аргумент командной строки после этого будет принято значение const. Увидеть описание nargs для примеров.