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