Python argparse: nargs='?' and optional arguments
Let's say I have a simple program called readfile.py
which supports command line arguments by using Python's argparse
.
The program reads from a file specified by the positional argument input
. Without specifying additional arguments, this program is not very exciting. It just reads from input
and exits. The optional argument --output [OUTPUT_FILE]
signifies that the input file should be written to a file. OUTPUT_FILE
is also optional. If it is not specified, the input should be written to default.out
.
I set up my argument parser like this:
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
Note I use default=None
so that if --ouput
doesn't appear on the command line, I can detect its absence with None.
Which gives a usage signature like this:
usage: readfile.py [-h] [--output [OUTPUT_FILE]] input
This handles arguments as expected if I run
python readfile.py input.in --output somefile.out
or
python readfile.py --output somefile.out input
It sets output
to default.out
if I run
python readfile.py input.in --output
but if I run
python readfile.py --output input.in
it complains about there being too few arguments. I thought argparse would be 'smart' enough to interpret this pattern, setting input
to input.in
and output
to default.out
. The generated usage even suggests this.
Am I missing something?
No, it will not recognize this. You are in the last example clearly passing in input.in
to --output
.
I would recommend that you flip the default
and the const
parameters. You want the default to be default.out, so it should be default='default.out'
. const
can then be set to something else for the case of having an empty --output
parameter.
That way you don't have to add the --output
parameter unless you want to change the default, and you can use an empty --output
parameter if you want to output to stdout
for example.
You can pass "--" to mark the end of any options. For instance:
python readfile.py --output -- input
has the intended effect. However, making the argument to --output required and allowing:
python readfile.py --output - input
is probably cleaner.
链接地址: http://www.djcxy.com/p/28554.html