1

my python version is 2.4.3.

Now I am developing a CLI with cmd module from python for a CD player. I have some classes like CDContainer (with method like addCD, removeCD, etc), CD (with method like play, stop, pause). Now, I want to add some options for the commands and also if the options inputs are not correct, the CLI could return proper information about either wrong input type or wrong values. e.g., I want to have "addcd --track 3 --cdname thriller". what I am doing now is to get all the arguments via , split it, and assign it to the relevant variables, as follows.

my question is in python, is there some module that is handy for my case to parse and analyse the options or arguments ?

REVISION: OK, I edit it, thanks to gclj5 comments.

import cmd
class CDContainerCLI(cmd.Cmd):

    def do_addcd(self, line):
        args=line.split()
        parser = OptionParser()
        parser.add_option("-t", "--track", dest="track_number", type="int",
            help="track number")
        parser.add_option("-n", "--cdname", dest="cd_name", type="string",
            help="CD name")
        (options, positional_args) = parser.parse_args(args)
        cd_obj= CD()
        cd_obj.addCD(options.track_number, options.cd_name)

If possible, could you write some code samples, just to show how to do it?

Thank you very much!!

3 Answers 3

3

Depending on your Python version, you should take a look at either optparse (since version 2.3, deprecated since version 2.7) or argparse (since version 2.7).

Some sample code using optparse (line is the string you read from stdin in your CLI):

from optparse import OptionParser

args = line.split()

parser = OptionParser()
parser.add_option("-t", "--track", dest="track_number", type="int",
                  help="track number")
parser.add_option("-n", "--cdname", dest="cd_name", type="string",
                  help="CD name")

# args[0] contains the actual command ("addcd" in this example).
(options, positional_args) = add_cd_parser.parse_args(args[1:])

if options.track_number != None and options.cd_name != None:
    cd_obj= CD()
    cd_obj.addCD(options.track_number, options.cd_name)
    print "add CD (track %d, name %s)" % (options.track_number, options.cd_name)

This parser only handles your "addcd" command. For more commands you could use several OptionParser objects in a dictionary with the command name as the key, for instance. You could parse the options like this then:

(options, args) = parsers[args[0]].parse_args(args[1:])

Take a look at the documentation for optparse for more information. It's very easy to output usage information, for instance. There is also a tutorial available.

Sign up to request clarification or add additional context in comments.

6 Comments

hi, gclj5, thank you for your answer. i am using 2.4.3. I heard about this optparse, but I do not know how to use it with my code. e.g. how could I integrate it into the addcd function? where and how should I add it?
I don't know about the exact structure of you program, so I can't tell you exactly where to add it. But I added some sample code to illustrate the usage of the optparse package. The general idea would be to let the CLI parsing code call the corresponding functions with the parsed options.
Hi, gclj5, thank you so much for your code. it is args[0:], not args[1:], because, the args are taken as the input for the method. I revise the code from my original post. but there is still some problem. when there is some exceptions(wrong type or missing option), this optionparse will exit for the whole program, instead of exit just for the relevant method. how could we solve this?
Just catch the exceptions and handle the errors on your own (informing the user and exiting the method). Also see the section How optparse handles errors in the optparse tutorial. BTW, you might as well use args directly (without [0:]) in your case.
hi, gclj5, so if I catch the exception and handle errors by myself, then the optparse will not be needed at all. is that right? this is a bit disappointing, just so close to have something handy, but at the end, I still could not use it.
|
3

my question is in python, is there some module that is handy for my case to parse and analyse the options or arguments ?

Yes, the argparse module.

If you're already familiar with the getopt library from C, that's also available as a python module - though less easy to use, if you're not already used to it.

Comments

1

Here's a demo script I wrote a few months ago when my co-workers and I were learning the argparse module. It illustrates several of the module's behaviors and features:

import sys
import argparse

def parse_command_line():
    # Define our argument parser.
    ap = argparse.ArgumentParser(
        description = 'This is a demo app for the argparse module.',
        epilog      = 'This text will appear after options.',
        usage       = '%(prog)s [options]',  # Auto-generated by default.
        add_help    = False,                 # Default is True.
    )

    # A grouping of options in the help text.
    gr = ap.add_argument_group('Required arguments')

    # A positional argument. This is indicated by the absense
    # of leading minus signs.
    gr.add_argument(
        'task',
        choices = ['get', 'put'],
        help = 'Task to be performed.', # Help text about an option.
        metavar = 'TASK', # Placeholder to be used in an option's help text.
                          # The default in this case would be "{get,put}".
    )

    # Another group.
    gr = ap.add_argument_group('Common options')

    # A basic option.
    gr.add_argument(
        '-s', '--subtask',
        action = 'store',  # This is the default.
                           # One value will be stored, as a string, 
                           # in opt.subtask
    )

    # A required option, with type conversion.
    gr.add_argument(
        '-u', '--user',
        required = True, # Options can be made mandatory.
                         # However, positional arguments can't be made optional.
        type = int,      # Convert opt.user to an integer.
                         # By default, it would be a string.
    )

    # A flag option.
    gr.add_argument(
        '--overwrite',
        dest = 'clobber',      # Store in opt.clobber rather than opt.overwrite.
        action = 'store_true', # If option is supplied, opt.clobber == True.
    )

    # Another group.
    gr = ap.add_argument_group('Some other options')

    # An option with multiple values.
    gr.add_argument(
        '--datasets',
        metavar = 'DATASET', # Default would be DATASETS.
        nargs = '+',  # If option is used, it takes 1 or more arguments.
                      # Will be stored as a list in opt.datasets.
        help = "The datasets to use for frobnication.",
    )

    # An option with a specific N of values.
    gr.add_argument(
        '--bar',
        nargs = 1,    # Takes exactly one argument. Differs from a basic
                      # option because opt.bar will be a list rather 
                      # than a string.
        default = [], # Default would be None.
    )

    # A file option.
    gr.add_argument(
        '--log',
        type    = argparse.FileType('w'),  # Will open a file for writing.
        default = sys.stdout,
        help    = 'Log file (default: STDOUT)',
    )

    # Another group.
    gr = ap.add_argument_group('Program information')

    # A version option.
    gr.add_argument(
        '-v', '--version',
        action = 'version', # Will display version text and exit.
        version = 'argparse_demo v1.2.0', # The version text.
    )

    # A help option.
    gr.add_argument(
        '-h', '--help',
        action = 'help', # Will display help text and exit.
    )

    # Parse the options.
    # If given no arguments, parse_args() works with sys.argv[1:].
    # And the object it returns will be of type Namespace.
    opt = ap.parse_args()

    return opt

command_lines = [
    'argparse_demo.py put -u 1',
    'argparse_demo.py get -u 234 --over --data a b c --bar XYZ -s munch --log _log.txt',
    'argparse_demo.py -h', # Will exit() here.
]

for c in command_lines:
    sys.argv = c.split()
    opt = parse_command_line()
    print opt

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.