understanding OptionParser

67.3k views Asked by At

I was trying out optparse and this is my initial script.

#!/usr/bin/env python

import os, sys
from optparse import OptionParser

parser = OptionParser()
usage = "usage: %prog [options] arg1 arg2"

parser.add_option("-d", "--dir", type="string",
                  help="List of directory",
                  dest="inDir", default=".")

parser.add_option("-m", "--month", type="int",
                  help="Numeric value of the month", 
                  dest="mon")

options, arguments = parser.parse_args()

if options.inDir:
    print os.listdir(options.inDir)

if options.mon:
    print options.mon

def no_opt()
    print "No option has been given!!"

Now, this is what I'm trying to do:

  1. If no argument is given with the option, it will take the "default" value. i.e myScript.py -d will just list the present directory or -m without any argument will take the current month as an argument.
  2. For the "--month" only 01 to 12 are allowed as an argument
  3. Want to combine more than one option for performing different tasks i.e. myScript.py -d this_dir -m 02 will do different thing than -d and -m as individual.
  4. It will print "No option has been given!!" ONLY if no option is supplied with the script.

Are these doable? I did visit the doc.python.org site for possible answers, but as a python-beginner, I found myself lost in the pages. It's very much appreciated your help; thanks in advance. Cheers!!


Update: 16/01/11

I think I'm still missing something. This is the thing in my script now.

parser = OptionParser()
usage = "usage: %prog [options] arg1 arg2"

parser.add_option("-m", "--month", type="string",
                  help="select month from  01|02|...|12",
                  dest="mon", default=strftime("%m"))

parser.add_option("-v", "--vo", type="string",
                  help="select one of the supported VOs",
                  dest="vos")

options, arguments = parser.parse_args()

These are my goal:

  1. run the script without any option, will return option.mon [working]
  2. run the script with -m option, with return option.mon [working]
  3. run the script with ONLY -v option, will ONLY return option.vos [not working at all]
  4. run the script with -m and -v opting, will do different thing [yet to get to the point]

When I run the script with only -m option, it's printing option.mon first and then option.vos, which I don't want at all. Really appreciate if anyone can put me in the right direction. Cheers!!


3rd Update

    #!/bin/env python

    from time import strftime
    from calendar import month_abbr
    from optparse import OptionParser

    # Set the CL options 
    parser = OptionParser()
    usage = "usage: %prog [options] arg1 arg2"

    parser.add_option("-m", "--month", type="string",
                      help="select month from  01|02|...|12", 
              dest="mon", default=strftime("%m"))

    parser.add_option("-u", "--user", type="string",
                      help="name of the user", 
              dest="vos")

    options, arguments = parser.parse_args()

    abbrMonth = tuple(month_abbr)[int(options.mon)]

    if options.mon:
        print "The month is: %s" % abbrMonth 

    if options.vos:
        print "My name is: %s" % options.vos 

    if options.mon and options.vos:
        print "I'm '%s' and this month is '%s'" % (options.vos,abbrMonth)

This is what the script returns when run with various options:

# ./test.py
The month is: Feb
#
# ./test.py -m 12
The month is: Dec
#
# ./test.py -m 3 -u Mac
The month is: Mar
My name is: Mac
I'm 'Mac' and this month is 'Mar'
#
# ./test.py -u Mac
The month is: Feb
My name is: Mac
I'm 'Mac' and this month is 'Feb'

I like to see only:

 1. `I'm 'Mac' and this month is 'Mar'` - as *result #3*  
 2. `My name is: Mac` - as *result #4*

what am I doing wrong? Cheers!!


4th Update:

Answering to myself: this way I can get what I'm looking for but I'm still not impressed though.

#!/bin/env python

import os, sys
from time import strftime
from calendar import month_abbr
from optparse import OptionParser

def abbrMonth(m):
    mn = tuple(month_abbr)[int(m)]
    return mn

# Set the CL options 
parser = OptionParser()
usage = "usage: %prog [options] arg1 arg2"

parser.add_option("-m", "--month", type="string",
                  help="select month from  01|02|...|12",
                  dest="mon")

parser.add_option("-u", "--user", type="string",
                  help="name of the user",
                  dest="vos")

(options, args) = parser.parse_args()

if options.mon and options.vos:
    thisMonth = abbrMonth(options.mon)
    print "I'm '%s' and this month is '%s'" % (options.vos, thisMonth)
    sys.exit(0)

if not options.mon and not options.vos:
    options.mon = strftime("%m")

if options.mon:
    thisMonth = abbrMonth(options.mon)
    print "The month is: %s" % thisMonth

if options.vos:
    print "My name is: %s" % options.vos

and now this gives me exactly what I was looking for:

# ./test.py 
The month is: Feb

# ./test.py -m 09
The month is: Sep

# ./test.py -u Mac
My name is: Mac

# ./test.py -m 3 -u Mac
I'm 'Mac' and this month is 'Mar'

Is this the only way of doing so? Doesn't look the "best way" to me. Cheers!!

3

There are 3 answers

0
feinmann On

Just to illustrate the choices-option of argparse.ArgumentParser's add_argument()-method:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from argparse import ArgumentParser
from datetime import date

parser = ArgumentParser()

parser.add_argument("-u", "--user", default="Max Power", help="Username")
parser.add_argument("-m", "--month", default="{:02d}".format(date.today().month),
                    choices=["01","02","03","04","05","06",
                             "07","08","09","10","11","12"],
                    help="Numeric value of the month")

try:
    args = parser.parse_args()
except:
    parser.error("Invalid Month.")
    sys.exit(0) 

print  "The month is {} and the User is {}".format(args.month, args.user)
0
jrennie On

Your solution looks reasonable to me. Comments:

  • I don't understand why you turn month_abbr into a tuple; it should work fine without the tuple()
  • I'd recommend checking for invalid month value (raise OptionValueError if you find a problem)
  • if you really want the user to input exactly "01", "02", ..., or "12", you could use the "choice" option type; see option types documentation
1
ninjagecko On

optparse is deprecated; you should use argparse in both python2 and python3

http://docs.python.org/library/argparse.html#module-argparse