views:

1761

answers:

9

The title says it all...what's the easiest, tersest, and most flexible method or library for parsing Python command line arguments?

+11  A: 

Use optparse which comes with the standard library. Here's a link describing how to use it:

http://www.ibm.com/developerworks/aix/library/au-pythocli/

Corey
+14  A: 

Pretty much everybody is using getopt

Here is the example code for the doc :

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

So in a word, here is how it works.

You've got two types of options. Those who are receiving an arguments, and those who are just like switches.

sys.argv is pretty much your char** argv in C. Like in C you skip the first element which is the name of your program and parse only the arguments : sys.argv[1:]

Getopt.getopt is will parse it according to the rule you give in argument.

"ho:v" here describes the short arguments : -ONELETTER. The : means that -o accepts one arguments.

Finally ["help", "output="] describes long arguments ( --MORETHANONELETTER ). The = after output once again means that output accepts one arguments.

The result is a list of couple (option,argument)

If an option doesn't accept any argument (like --help here) the arg part is an empty string. You then usually want to loop on this list and test the option name as in the example.

I hope this helped you.

poulejapon
+1  A: 

The title doesn't say it all :)


best != easiest and tersest


I think the best way is the optparse way but that's certainly not the tersest ;)

sparkes
+3  A: 

Just in case you might need to, this may help if you need to grab unicode arguments on Win32 (2K, XP etc):


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()
Shadow2531
+3  A: 

I prefer optparse to getopt. It's very declarative: you tell it the names of the options and the effects they should have (e.g., setting a boolean field), and it hands you back a dictionary populated according to your specifications.

http://docs.python.org/lib/module-optparse.html

Chris Conway
+31  A: 

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 optparse

parser = 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

Thomas Vander Stichele
@Silfheed's suggestion of argparse seems even better. code.google.com/p/argparse
hayalci
+2  A: 

I think the best way for larger projects is optparse, but if you are looking for an easy way, maybe http://werkzeug.pocoo.org/documentation/script is something for you.

from werkzeug import script

# actions go here
def action_foo(name=""):
    """action foo does foo"""
    pass

def action_bar(id=0, title="default title"):
    """action bar does bar"""
    pass

if __name__ == '__main__':
    script.run()

So basically every function action_* is exposed to the command line and a nice help message is generated for free.

python foo.py 
usage: foo.py <action> [<options>]
       foo.py --help

actions:
  bar:
    action bar does bar

    --id                          integer   0
    --title                       string    default title

  foo:
    action foo does foo

    --name                        string
Peter Hoffmann
+1  A: 

Check out commandlineapp. It makes things a lot easier to handle imo. http://blog.doughellmann.com/2008/06/commandlineapp-30.html

Rick
+11  A: 

The new hip way is argparse for these reasons. argparse > optparse > getopt

Silfheed