Simple argparse example wanted: 1 argument, 3 results

The documentation for the argparse python module, while excellent I'm sure, is too much for my tiny beginner brain to grasp right now. I don't need to do math on the command line or meddle with formatting lines on the screen or change option characters. All I want to do is "If arg is A, do this, if B do that, if none of the above show help and quit".


Solution 1:

Here's the way I do it with argparse (with multiple args):

parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())

args will be a dictionary containing the arguments:

if args['foo'] == 'Hello':
    # code here

if args['bar'] == 'World':
    # code here

In your case simply add only one argument.

Solution 2:

My understanding of the original question is two-fold. First, in terms of the simplest possible argparse example, I'm surprised that I haven't seen it here. Of course, to be dead-simple, it's also all overhead with little power, but it might get you started.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
    print 'You nailed it!'

But this positional argument is now required. If you leave it out when invoking this program, you'll get an error about missing arguments. This leads me to the second part of the original question. Matt Wilkie seems to want a single optional argument without a named label (the --option labels). My suggestion would be to modify the code above as follows:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
    print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
    print 'You nailed it!'
else:
    print args.a

There may well be a more elegant solution, but this works and is minimalist.

Solution 3:

The argparse documentation is reasonably good but leaves out a few useful details which might not be obvious. (@Diego Navarro already mentioned some of this but I'll try to expand on his answer slightly.) Basic usage is as follows:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

The object you get back from parse_args() is a 'Namespace' object: An object whose member variables are named after your command-line arguments. The Namespace object is how you access your arguments and the values associated with them:

args = parser.parse_args()
print (args.my_foo)
print (args.bar_value)

(Note that argparse replaces '-' in your argument names with underscores when naming the variables.)

In many situations you may wish to use arguments simply as flags which take no value. You can add those in argparse like this:

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

The above will create variables named 'foo' with value True, and 'no_foo' with value False, respectively:

if (args.foo):
    print ("foo is true")

if (args.no_foo is False):
    print ("nofoo is false")

Note also that you can use the "required" option when adding an argument:

parser.add_argument('-o', '--output', required=True)

That way if you omit this argument at the command line argparse will tell you it's missing and stop execution of your script.

Finally, note that it's possible to create a dict structure of your arguments using the vars function, if that makes life easier for you.

args = parser.parse_args()
argsdict = vars(args)
print (argsdict['my_foo'])
print (argsdict['bar_value'])

As you can see, vars returns a dict with your argument names as keys and their values as, er, values.

There are lots of other options and things you can do, but this should cover the most essential, common usage scenarios.

Solution 4:

Matt is asking about positional parameters in argparse, and I agree that the Python documentation is lacking on this aspect. There's not a single, complete example in the ~20 odd pages that shows both parsing and using positional parameters.

None of the other answers here show a complete example of positional parameters, either, so here's a complete example:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

The thing that threw me off is that argparse will convert the named argument "--foo-bar" into "foo_bar", but a positional parameter named "foo-bar" stays as "foo-bar", making it less obvious how to use it in your program.

Notice the two lines near the end of my example -- neither of those will work to get the value of the foo-bar positional param. The first one is obviously wrong (it's an arithmetic expression args.foo minus bar), but the second one doesn't work either:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

If you want to use the foo-bar attribute, you must use getattr, as seen in the last line of my example. What's crazy is that if you tried to use dest=foo_bar to change the property name to something that's easier to access, you'd get a really bizarre error message:

ValueError: dest supplied twice for positional argument

Here's how the example above runs:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

optional arguments:
  -h, --help  show this help message and exit

$ python test.py install foo
You asked for installation
foo