您的位置:首页 > 运维架构

Python - Parser for command line options - optparse

2012-12-22 14:03 881 查看

1 optparse

Let's start with an example.

parser.py

from optparse import OptionParser

usage = "usage: %prog [options] arg1 arg2"
version = "%prog 1.0"
parser = OptionParser(usage = usage, version = version)#arguments usage,version are optional
parser.add_option("-v", "--verbose",
action = "store_true", dest = "verbose",
default = True, help = "make lots of noise [default]")
parser.add_option("-q", "--quiet",
action = "store_false", dest = "verbose",
help = "be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
metavar = "FILE", help = "write output to file")
parser.add_option("-m", "--mode",
default = "intermediate",
help = "interaction mode: novice, intermediate, "
"or expect [default: %default]")

(options, args) = parser.parse_args()


下面解释一下吧:

(1)Understanding option actions

(a)The store action

The most common option action is store, which tells optparse to take the next argument (or the remainder of the current argument), ensure that it is of the correcttype, and
store it to your chosen destination.

For example:

store1.py

from optparse import OptionParser
parser = OptionParser()
parser.add_option("-f", "--file", action = "store",
type = "string", dest = "filename")
(options, args) = parser.parse_args()
print("options:", options)
print("args:", args)
print("options.filename:", options.filename)


结果如下:



When optparse sees the option string -f, it consumes the next argument, foo.txt, and stores it in options.filename.

Some other option types supported by optparse areint andfloat. Here’s an option that expects an integer argument:

parser.add_option("-n", type="int", dest="num")


If you don’t specify a type, optparse assumes string. Combined with the fact that the default action is store, that means our first example can be a lot shorter:

parser.add_option("-f", "--file", dest="filename")


(b)Handling boolean (flag) options

Flag options—set a variable to true or false when a particular option is seen —are quite common. optparse supports them with two separate actions,store_true andstore_false.
For example, you might have a verbose flag that is turned on with-v and off with-q:

store2.py

from optparse import OptionParser

parser = OptionParser()
parser.add_option("-v", action="store_true", dest="verbose")  # -v
parser.add_option("-q", action="store_false", dest="verbose") # -q

(options, args) = parser.parse_args()
print(options.verbose)


Here we have two different options with the same destination, which is perfectly OK.

When optparse encounters -v on the command line, it setsoptions.verbose toTrue; when it encounters -q,options.verbose is set toFalse.



(c)Other actions

Some other actions supported by optparse are:

"store_const" store a constant value

"append" append this option’s argument to a list

"count" increment a counter by one

"callback" call a specified function

(2)Default values

optparse lets you supply a default value for each destination, which is assigned before the command line is parsed.

First, consider the verbose/quiet example. If we want optparse to set verbose to True unless -q is seen, then we can do this:

parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")


Since default values apply to the destination rather than to any particular option, and these two options happen to

have the same destination, this is exactly equivalent:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)


A clearer way to specify default values is the set_defaults() method of OptionParser, which you can call at any time before calling parse_args():

parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()


(3)Generating help

Let's see parser.py above.

If optparse encounters either -h or --help on the command-line, it prints the following to standard output:



There’s a lot going on here to help optparse generate the best possible help message:

(a)the script defines its own usage message:

usage = "usage: %prog [options] arg1 arg2"


optparse expands %prog in the usage string to the name of the current program.

(b)options that take a value indicate this fact in their automatically-generated help message, e.g. for the “mode” option:

-m MODE, --mode=MODE

Here, “MODE” is called the meta-variable: it stands for the argument that the user is expected to supply to -m/--mode. By default, optparse converts the destination variable name to uppercase and uses that for the meta-variable. Sometimes, that’s not
what you want—for example, the --filename option explicitly sets metavar="FILE", resulting in this automatically-generated option description:

-f FILE, --filename=FILE

(c)options that have a default value can include
%default
in the help string—optparse will replace it with str() of the option’s default value.

(4)Grouping Options

When dealing with many options, it is convenient to group these options for better help output.

OptionParser can contain several option groups, each of which can contain several options.

An An option group is obtained using the class OptionGroup:

class optparse.OptionGroup(parser, title, description=None)

where

•parser is the OptionParser instance the group will be insterted in to

•title is the group title

•description, optional, is a long description of the group

OptionGroup inherits from OptionContainer (like OptionParser) and so theadd_option() method can be used to add an option to the group.

Once all the options are declared, using the OptionParser methodadd_option_group()the group is added to the previously defined parser.

Continuing with the parser defined in parser.py, adding an OptionGroup to a parser is easy:

# OptionGroup
from optparse import OptionGroup
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action = "store_true", help = "GroupOption.")
parser.add_option_group(group)


This would result in the following help output:



A bit more complete example might involve using more than one group: still extendingparser.py:

# OptionGroup
group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action = "store_true",
help = "Print debug information")
group.add_option("-s", "--sql", action = "store_true",
help = "Print all SQL statements executed")
group.add_option("-e", action = "store_true",
help = "Print every action done")
parser.add_option_group(group)


hat results in the following output:



(5)Option attributes

The following option attributes may be passed as keyword arguments toOptionParser.add_option().

(a)Option.action

(default: "store") Determines optparse‘s behaviour when this option is seen on the command line

(b)Option.type

(default: "string") The argument type expected by this option (e.g., "string" or "int")

(c)Option.dest

(default: derived from option strings)

If the option’s action implies writing or modifying a value somewhere, this tells optparse where to write it: dest names an attribute of the options object that optparse builds as it parses the command line.

(d)Option.default

The value to use for this option’s destination if the option is not seen on the command line.

(e)Option.nargs

(default: 1) How many arguments of type type should be consumed when this option is seen. If > 1, optparse will

store a tuple of values to dest.

For example:

parser.add_option("-f")
parser.add_option("-p", type="float", nargs=3, dest="point")


As it parses the command line:

-f foo.txt -p 1 -3.5 4 -fbar.txt

optparse will set:

options.f = "foo.txt"

options.point = (1.0, -3.5, 4.0)

options.f = "bar.txt"

(f)Option.callback

For options with action "callback", the callable to call when this option is seen.

(g)Option.help

Help text to print for this option when listing all available options after the user supplies a help option (such as --help). If no help text is supplied, the option will be listed without help text.

(h)Option.metavar

(default: derived from option strings) Stand-in for the option argument(s) to use when printing help text.

(6)A Jython example:

builder.py

A script that will help handle the compilation of java files to .class files in a directory, and clean the directory of .class files as a separate task. We will want to be able to create a directory structure, delete the directory structure
for a clean build, and of course compile our java source files.

import os
import sys
import glob

from javax.tools import (ForwardingJavaFileManager, ToolProvider,
DiagnosticCollector, )

tasks = {}

def task(func):
tasks[func.func_name] = func

@task         # decorator
def clean():
files = glob.glob("*.class")
for file in files:
os.unlink(file)

@task
def compile():
files = glob.glob("*.java")
_log("compiling %s" %(files))
if not _compile(files):
quit()
_log("compiled")

def _log(message):
if options.verbose:
print(message)

def _compile(names):
compiler = ToolProvider.getSystemJavaCompiler()
diagnostics = DiagnosticCollector()
manager = compiler.getStandardFileManager(diagnostics, None, None)
units = manager.getJavaFileObjectsFromStrings(names)
comp_task = compiler.getTask(None, manager, diagnostics, None, None, units)
success = comp_task.call()
manager.close()
return success

if __name__ == "__main__":
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-q", "--quiet", action = "store_false", dest = "verbose",
default = True, help = "don't print out task message.")
parser.add_option("-p", "--projecthelp", action = "store_true",
dest = "projecthelp", help = "print out list of tasks.")
(options, args) = parser.parse_args()
"""
print("-------------------")
print(options)
print(args)
print("-------------------")
"""
if options.projecthelp:
for task in tasks:
print task
sys.exit(0)
if len(args) < 1:
print("Usage: jython builder.py [options] task")
sys.exit(1)

try:
current = tasks[args[0]]
except KeyError:
print("task %s not defined." %(args[0]))
current()






example2.py

import sys
from optparse import OptionParser

greetings = dict(en = "Hello %s!",
es = "Hola %s!",
fr = "Bonjour %s!",
pt = "Alo %s!")

uis = {}
def register_ui(ui_name):
def decorator(f):
uis[ui_name] = f    # value of uis is a function
return f
return decorator

def message(ui, msg):
if ui in uis:
uis[ui](msg)
else:
raise ValueError("No greeter named %s" %(ui))

def list_uis():
return uis.keys()

@register_ui("console")
def print_message(msg):
print msg

@register_ui("windows")
def show_message_as_window(msg):
from javax.swing import JFrame, JLabel
frame = JFrame(msg, defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
size = (100, 100), visible = True)
frame.contentPane.add(JLabel(msg))

if __name__ == "__main__":
parser = OptionParser()
parser.add_option("--ui", dest = "ui", default = "console",
help = "Sets the UI to use to greet the user."
"One of: %s" % ",".join("'%s'" % ui for ui in list_uis()))
parser.add_option('--lang', dest='lang', default='en',
help="Sets the language to use")
options, args = parser.parse_args()
#options, args = parser.parse_args(sys.argv)
print uis
print options
print args
'''
if len(args) < 2:
print "Sorry, I can't greet you if you don't say your name"
sys.exit(1)
'''
if options.lang not in greetings:
print "Sorry, I don't speak '%s'" % options.lang
sys.exit(1)
msg = greetings[options.lang] % args[0]
#msg = greetings[options.lang] % args[1]
try:
message(options.ui, msg)
except ValueError, e:
print "Invalid UI name\n"
print "Valid UIs:\n\n" + "\n".join(' * ' + ui for ui in list_uis())
sys.exit(1)


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: