What's the best way to parse command line arguments? [closed]
argparse
is the way to go. Here is a short summary of how to use it:
1) Initialize
import argparse# Instantiate the parserparser = argparse.ArgumentParser(description='Optional app description')
2) Add Arguments
# Required positional argumentparser.add_argument('pos_arg', type=int, help='A required integer positional argument')# Optional positional argumentparser.add_argument('opt_pos_arg', type=int, nargs='?', help='An optional integer positional argument')# Optional argumentparser.add_argument('--opt_arg', type=int, help='An optional integer argument')# Switchparser.add_argument('--switch', action='store_true', help='A boolean switch')
3) Parse
args = parser.parse_args()
4) Access
print("Argument values:")print(args.pos_arg)print(args.opt_pos_arg)print(args.opt_arg)print(args.switch)
5) Check Values
if args.pos_arg > 10: parser.error("pos_arg cannot be larger than 10")
Usage
Correct use:
$ ./app 1 2 --opt_arg 3 --switchArgument values:123True
Incorrect arguments:
$ ./app foo 2 --opt_arg 3 --switchusage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]app: error: argument pos_arg: invalid int value: 'foo'$ ./app 11 2 --opt_arg 3Argument values:1123Falseusage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]convert: error: pos_arg cannot be larger than 10
Full help:
$ ./app -husage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]Optional app descriptionpositional arguments: pos_arg A required integer positional argument opt_pos_arg An optional integer positional argumentoptional arguments: -h, --help show this help message and exit --opt_arg OPT_ARG An optional integer argument --switch A boolean switch
This answer suggests optparse
which is appropriate for older Python versions. For Python 2.7 and above, argparse
replaces optparse
. See this answer for more information.
As other people pointed out, you are better off going with optparse over getopt. getopt is pretty much a one-to-one mapping of the standard getopt(3) C library functions, and not very easy to use.
optparse, while being a bit more verbose, is much better structured and simpler to extend later on.
Here's a typical line to add an option to your parser:
parser.add_option('-q', '--query', action="store", dest="query", help="query string", default="spam")
It pretty much speaks for itself; at processing time, it will accept -q or --query as options, store the argument in an attribute called query and has a default value if you don't specify it. It is also self-documenting in that you declare the help argument (which will be used when run with -h/--help) right there with the option.
Usually you parse your arguments with:
options, args = parser.parse_args()
This will, by default, parse the standard arguments passed to the script (sys.argv[1:])
options.query will then be set to the value you passed to the script.
You create a parser simply by doing
parser = optparse.OptionParser()
These are all the basics you need. Here's a complete Python script that shows this:
import optparseparser = optparse.OptionParser()parser.add_option('-q', '--query', action="store", dest="query", help="query string", default="spam")options, args = parser.parse_args()print 'Query string:', options.query
5 lines of python that show you the basics.
Save it in sample.py, and run it once with
python sample.py
and once with
python sample.py --query myquery
Beyond that, you will find that optparse is very easy to extend.In one of my projects, I created a Command class which allows you to nest subcommands in a command tree easily. It uses optparse heavily to chain commands together. It's not something I can easily explain in a few lines, but feel free to browse around in my repository for the main class, as well as a class that uses it and the option parser
Using docopt
Since 2012 there is a very easy, powerful and really cool module for argument parsing called docopt. Here is an example taken from its documentation:
"""Naval Fate.Usage: naval_fate.py ship new <name>... naval_fate.py ship <name> move <x> <y> [--speed=<kn>] naval_fate.py ship shoot <x> <y> naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting] naval_fate.py (-h | --help) naval_fate.py --versionOptions: -h --help Show this screen. --version Show version. --speed=<kn> Speed in knots [default: 10]. --moored Moored (anchored) mine. --drifting Drifting mine."""from docopt import docoptif __name__ == '__main__': arguments = docopt(__doc__, version='Naval Fate 2.0') print(arguments)
So this is it: 2 lines of code plus your doc string which is essential and you get your arguments parsed and available in your arguments object.
Using python-fire
Since 2017 there's another cool module called python-fire. It can generate a CLI interface for your code with you doing zero argument parsing. Here's a simple example from the documentation (this small program exposes the function double
to the command line):
import fireclass Calculator(object): def double(self, number): return 2 * numberif __name__ == '__main__': fire.Fire(Calculator)
From the command line, you can run:
> calculator.py double 1020> calculator.py double --number=1530