Commandline Parsing with argparse
¶
Basics¶
Commandline parsing using only raw
sys.argv
is tedious (see here)Nobody wants positional arguments
Error checking is rarely done correctly ⟶
IndexError
when accessing an argument the user didn’t pass
The following program would be called like so …
$ python raw.py 0.5 samples.csv
import sys
interval = float(sys.argv[1])
outputfilename = sys.argv[2]
# ...
If the user didn’t give the filename argument, position 2 would be
invalid in sys.argv
…
$ python raw.py 0.5
Traceback (most recent call last):
File "/home/jfasch/work/jfasch-home/trainings/material/soup/python/drafts/argparse/raw.py", line 4, in <module>
outputfilename = sys.argv[2]
IndexError: list index out of range
Handling Positional Arguments¶
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('interval', type=float, help='interval (in seconds) that we retrieve samples')
parser.add_argument('outputfilename', help='file to write samples to ("-" for stdout)')
args = parser.parse_args()
interval = args.interval
outputfilename = args.outputfilename
# ...
Omitting the second (filename) argument leads to an error, clearly, but that comes with a usage message,
$ python positional.py 0.5
usage: positional.py [-h] interval outputfilename
positional.py: error: the following arguments are required: outputfilename
The user will then say what she is suggested,
$ python positional.py -h
usage: positional.py [-h] interval outputfilename
positional arguments:
interval interval (in seconds) that we retrieve samples
outputfilename file to write samples to ("-" for stdout)
optional arguments:
-h, --help show this help message and exit
Ah:
$ python positional.py 0.5 samples.csv
...
The type
parameter to add_argument()
helps, too,
$ python positional.py 0,5 samples.csv
usage: positional.py [-h] interval outputfilename
positional.py: error: argument interval: invalid float value: '0,5'
Handling Named Arguments: --interval
…¶
Most people prefer named arguments over positional arguments, for readability …
$ python named.py --interval 0.5 --outputfilename samples.csv
...
This is as simple as …
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--interval', type=float, help='interval (in seconds) that we retrieve samples')
parser.add_argument('-o', '--outputfilename', help='file to write samples to ("-" for stdout)')
args = parser.parse_args()
interval = args.interval
outputfilename = args.outputfilename
# ...
The command can then be invoked in many ways …
$ python named.py --interval 0.5 --outputfilename samples.csv
$ python named.py -i 0.5 -o samples.csv
$ python named.py --int 0.5 --ou samples.csv