Saving yourself from command line parsing hell with argparse
argparse, I thought the only way to deal with command line arguments was to use
sys.argv. You throw a series of arguments at a program, munge through them with
sys.argv, etc. and hope for the best. And you hope that you always have full control over the arguments coming at your program through the command line. But what do you do if you have optional arguments, or flags? You could write your own parsers to handle all of that, but that's where
argparse comes in.
argparse provides a wrapper around
sys.argv that... well, it parses arguments. The name is rather intuitive.
A program utilizing
argparse requires an
ArgumentParser object to be much use at all. The arguments supplied to the
ArgumentParser upon initialization provide much of the information on how we'll use the tool. We'll do that like so:
parser = argparse.ArgumentParser(description='A custom tool for rustling or unrustling jimmies.', usage='Use the custom tool in a manner that keeps your jimmies unrustled.')
The "description" and "usage" strings provide information that will be displayed when a user wants to read the manual on your program. We'll look at that output in a bit once we add some arguments.
parser.add_argument('jimmies', type=int, nargs='+', help='Jimmies, in this instance, are a list of integers delimited by spaces.')
I've added an argument here that will be named 'jimmies.' By design, any argument that does not have a '-' preceding its name is a positional argument.
jimmies expects arguments to be integers (
type=int) and everything supplied on the command line will be cobbled together into a list (
nargs='+'). We've also provided some help text here.
parser.add_argument('--rustle', dest='rustle', action='store_const', const=shuffle, default=unshuffle, help='The rustle flag determines if you would like further rustling of your jimmies. Otherwise, this program will naturally seek unrustlement.')
I've now added an optional flag here called
--rustle. This will send everything into a function called
rustle will do one of two things here: it will either make use of a function called
shuffle if the flag is present, or it will make use of a function called unshuffle if the flag is absent. The
action parameter indicates that we should store a constant value regardless. We'll use a default value if the
--rustle flag isn't present, but we'll use the
Let's assume that
shuffle() were defined elsewhere in the program like so.
import random def unshuffle(parsed_items): parsed_items.sort() return parsed_items def shuffle(parsed_items): random.shuffle(parsed_items) return parsed_items
Then finally, we have to use the program:
if __name__ == "__main__": args = parser.parse_args() print args.rustle(args.jimmies)
args = parser.parse_args() will produce a list of arguments based on what was supplied at the command-line. Now that we have some
args in our namespace, we can
$ python argparse-example.py --help usage: Use the custom tool in a manner that keeps your jimmies unrustled. A custom tool for rustling or unrustling jimmies. positional arguments: jimmies Jimmies, in this instance, are a list of integers delimited by spaces. optional arguments: -h, --help show this help message and exit --rustle The rustle flag determines if you would like further rustling of your jimmies. Otherwise, this program will naturally seek unrustlement. $ python argparse-example.py 4 8 1 2 [1, 2, 4, 8] $ python argparse-example.py 4 8 1 2 --rustle [2, 8, 1, 4]