optparse 命令行选项模块

源地址:http://blog.csdn.net/kapuliyuehan/article/details/7421817

optparse是一个比getopt模块更方便、灵活、强大的库,它主要用来解析命令行选项。optparse使用如下方式来解析命令行选项:你创建一个OptionParser实例, 填充选项, 解析命令行. optparse允许用户以传统的GNU/POSIX语义指定选项,此外还能为你产生使用说明和帮助信息。

optparse采用预先定义好的选项来解析命令行参数,optparse默认就是解析命令行参数的。

下面是一个使用optparse的简单脚本:

from optparse import OptionParser
[...]
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
                  help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose", default=True,
                  help="don't print status messages to stdout")
(options, args) = parser.parse_args()

你的脚本用户能够在命令行做如下操作:

<yourscript> --file=outfile -q

optparse基于用户输入的命令行值,通过调用parse_args() 函数来设置options对象的属性。当parse_args() 函数返回后,

options.filename会是"outfile"options.verbose会是Falseoptparse 支持长和短选项,允许短选项合并,允许选项和它们的参数以多种不同方式关联。因此,下面的命令行输入是等价的:

<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile

另外,用户能够通过下面的命令行来获取帮助

<yourscript> -h
<yourscript> --help

optparse会打印出你脚本选项的简短概述:

Usage: <yourscript> [options]

Options:
  -h, --help            show this help message and exit
  -f FILE, --file=FILE  write report to FILE
  -q, --quiet           don't print status messages to stdout

yourscript的值在运行时决定(通常来自于sys.argv[0]).


15.5.1. Background

optparse被设计用于鼓励以传统的命令行接口来创建应用程序。它只支持在Unix下使用的最通用的命令行语义和语法。

15.5.1.1. 术语

argument

命令行上输入的字符串,被shell传递给execl() or execv()。在python中,参数是sys.argv[1:] (sys.argv[0]是被执行程序的名字)。Unix shells也使用术语"word"。

它用于取代参数列表。这里的参数列表不仅仅是sys.argv[1:],也可能是另一些列表形式。因此你应该把argument当作sys.argv[1:]的一个元素或者其它列表的一个元素。

option

一个argument被用于给程序提供信息,以自定义的方式来执行程序。选项有多个不同的语法,传统的Unix语法是使用连字符带一个字母 , e.g. -x or -F. 传统的Unix syntax 也允许多个选项合并为单个argument, e.g. -x -F is equivalent to -xF. GNU项目引入--, e.g. --file or --dry-run. 这两种方式是optparse目前所支持的.其它方式暂不支持,以后也不会。

option argument

紧跟在option之后的一个argument是与这个option相关的, 此argument会被此选项所使用。使用optparse, option arguments 可以和option分离:

-f foo
--file foo

也可以和option合并在一起:

-ffoo
--file=foo

一个选项要么带argument要么不带. 许多人想要“optional option arguments(可选的选项参数)” 功能,这意味着选项可以带参数也可以不带。这有些争议,因为它会使解析发生歧义:如果-a和-b的参数都是可选的,那我们如何解析-ab? 因为歧义optparse 不支持这一功能.

positional argument
在options之后剩余的argumen
required option
一个必须在命令行给定的; optparse 并不阻止你实现required option, 但它也没有任何帮助提供.

例如:

prog -v --report /tmp/report.txt foo bar

-v and --report是options. 假设--report带一个参数, /tmp/report.txt是option argument. foobar是positional arguments.

15.5.1.2. What are options for?

Options被用于提供信息来自定义程序的执行。选项通常是可选的.一个程序应该能够在没有options时也能运行。

15.5.1.3. What are positional arguments for?

Positional arguments是你的应用程序运行绝对需要的信息。

一个好的用户接口应该尽可能有少的绝对需求。当你的应用程序有太多信息需要提供,很多人会选择放弃。

总之,尽可能减少用户需要提供绝对信息的数量。灵活性和复杂性是相对的,越灵活越复杂,需要在灵活性和复杂性之间做出权衡。越灵活也越难维护。

15.5.2. 教程

因为optparse是如此灵活强大, 在大多数情况下可以直接使用. 本节覆盖比较常用的基于optparse的程序.

首先, 你需要导入OptionParser类; 然后, 在main程序中,创建OptionParser实例:

from optparse import OptionParser
[...]
parser = OptionParser()

然后你定义option. 基本语法是:

parser.add_option(opt_str, ...,
                  attr=value, ...)

每个option有一个或多个option字符串, 如-f--file, 几个option属性,这些属性告诉optparse需要什么及在命令行碰到这一option如何处理。

典型的,各个option有一个短option字符串和一个长的option字符串, e.g.:

parser.add_option("-f", "--file", ...)

你可以定义0个或多个短option字符串和长的option字符串,只要有一个option字符串即可。

option字符串传递给add_option()是定义的有效标签.optparse碰到命令行option字符串时,会从这些有效标签中寻找对应的option。

一旦所有的options已经定义,指示optparse解析命令行参数:

(options, args) = parser.parse_args()

(如果你喜欢,你可以自定义参数列表传递给parse_args(), 虽然这很少用: 默认使用sys.argv[1:].)

parse_args() 返回两个值:

  • options, 一个对象,它包含所有options的值—e.g.如果--file带单个字符串参数,然后options.file就会是用户提供的文件名, 如果用户未提供则是None
  • args, 选项解析之后的positional arguments

本教程只覆盖以下四个重要的option属性: actiontypedest (destination), and help. 其中, action是最基本的.

15.5.2.1. 理解option actions

Actions告诉optparse在命令行碰到一个option时做什么。有一个固定的actions集合硬编码到optparse;增加新的actions是一个高级课题,它在Extending optparse有介绍. 大多数的actions告诉optparse在某个变量中存储值,—例如, 从命令行获取一个字符串,然后存储在options的属性中。

如果你没有指定option action,optparse缺省是store.

15.5.2.2. store action

最常用的option action是store, 它告诉optparse获取下一个参数 (or当前参数的剩余部分), 确保它是正确的类型,然后存储到指定的目标。

例如:

parser.add_option("-f", "--file",
                  action="store", type="string", dest="filename")

现在让我们做一个命令行的替身,请optparse来解析:

args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)

optparse看到-f,它使用了下一个参数foo.txt,然后存储到options.filename.因此,在调用parse_args()options.filename"foo.txt".

optparse支持的其它option类型有int and float. 下面的option需要一个整数:

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

注意这个option没有长option字符串,也没有显式声明的action,因此缺省值为store.

让我们来解析另一个命令行替身。这次,我们使option argument紧挨着option:因此-n42-n 42是相等的:

(options, args) = parser.parse_args(["-n42"])
print options.num

打印42.

如果你没有指定类型,optparse假定为string. 结合缺省action是store,这意味着我们的第一个例子可以更加简短:

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

如果你没有提供目标,optparse会从option字符串中估算一个合理的缺省值:如果第一个长option字符串是--foo-bar, 缺省目标是foo_bar. 如果没有长option字符串, optparse查看第一个短option字符串:-f的缺省目标是f.

optparse也包含内建的longcomplex类型. Adding types is covered in section Extending optparse.

15.5.2.3. boolean (flag) options 的处理

标识options—设置一个变量为true或false.optparse有两个独立的actions来支持这个特性, store_truestore_false. For example, 你可能有一个verbose标识,-v表示打开,-q表示关闭:

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

我们有两个不同的options存储到相同的目标,两个都是正确的。(只是在设置缺省值时你需要留意一下)

optparse碰到-v, 它设置options.verbose为真;碰到-qoptions.verbose设置为假.

15.5.2.4. 其它actions

Some other actions supported by optparse are:

"store_const"
存储一个常量值
"append"
附加这个option的argument到一个列表
"count"
increment a counter by one
"callback"
调用一个指定的函数

These are covered in section Reference Guide, Reference Guide and section Option Callbacks.

15.5.2.5. Default values(缺省值)

以上的例子都是将碰到某个option时,设置某个值。如果没有碰到这些option呢。因为我们未提供缺省值,他们都会被设置为None。这通常是合理的,但是有时你想要更多的控制。optparse让你为各个目标提供缺省值,在命令行在解析前就会被赋予这些值.

首先,考虑verbose/quiet例子. 如果我们想要optparsed在没有碰到-q时verboseTrue:

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

因为缺省值是赋给目标而不是某个特定的option,下面与上面的相等的:

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

考虑如下:

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

verbose 缺省会是True: 目标会使用最后计算的缺省值.

一个指定目标缺省值更清晰的方式是OptionParserset_defaults()方法,在调用parse_args()之前调用此方法:

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

尽量不要使用两种方式来设置缺省值,以免混乱。


15.5.2.6. 产生help

optparse能产生友好的帮助和使用信息. 你要做的就是为各个option提供一个help值和整个程序的一个可选的简短使用信息.下面是一个实例:

usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
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 expert [default: %default]")

如果optparse在命令行碰到-h--help, 或者你调用parser.print_help(), 它将会打印下面的输出:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

下面有一些建议能帮助optparse产生更好的帮助信息:

  • 脚本使用信息:

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

    optparse扩展%prog为当前程序名, i.e. os.path.basename(sys.argv[0]).扩展字符串会在打印帮助信息时打印出来.

  • 每个option定义一个help字符串, 不要担心换行问题— optparse会考虑这个并使它看起来美观.

  • options在自动产生的帮助信息中带一个值, e.g. for the “mode” option:

    -m MODE, --mode=MODE

    这里,“MODE”叫做meta-variable: 它表示-m/--mode期待的值. 缺省情况下, optparse转换目标名称为大写并使用它作为 meta-variable.有时,这并不是你需要的—for example,--filename option 显式设置了metavar="FILE", 导致自动产生的帮助信息如下:

    -f FILE, --filename=FILE

在version 2.4中:options 能够包含一个%default在帮助字符串中,optparse会将这个option的缺省值转换为字符串替换它,如果没有缺省值,%default扩展为none.

15.5.2.6.1. 组合Options

如果有许多options,把这些option分组为获得更好的帮助信息.一个OptionParser能够包含多个option组,每个组包含多个options.

一个option组通过使用类OptionGroup获得:

class optparse.OptionGroup(parsertitledescription=None)

where

  • parser是这个组将要插入的OptionParser实例
  • title是组标题
  • description, 可选项,是组的一个长的描述

OptionGroup继承自OptionContainer (like OptionParser) and 因此可以使用add_option()增加选项到组.

一旦所有选项都声明好了,使用OptionParser方法add_option_group(),这个组就被加入到先前定义的parser中了。

继续先前定义的parser实例,增加OptionGroup给parser是一件很容易的事情:

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="Group option.")
parser.add_option_group(group)

这将会产生下面的帮助信息:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                        expert [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

下面是一个更加复杂的实例,有多个组:

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="Group option.")
parser.add_option_group(group)

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)

that results in the following output:

Usage: <yourscript> [options] arg1 arg2

Options:
  -h, --help            show this help message and exit
  -v, --verbose         make lots of noise [default]
  -q, --quiet           be vewwy quiet (I'm hunting wabbits)
  -f FILE, --filename=FILE
                        write output to FILE
  -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert
                        [default: intermediate]

  Dangerous Options:
    Caution: use these options at your own risk.  It is believed that some
    of them bite.

    -g                  Group option.

  Debug Options:
    -d, --debug         Print debug information
    -s, --sql           Print all SQL statements executed
    -e                  Print every action done

Another interesting method, in particular when working programmatically with option groups is:

OptionParser.get_option_group(opt_str)

Return the OptionGroup to which the short or long option string opt_str (e.g. '-o' or '--option') belongs. If there’s no such OptionGroup, return None.

15.5.2.7. 打印version字符串

optparse也可以打印一个版本信息. 你需要提供version参数给OptionParser:

parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

当你提供version参数,optparse自动增加--version option 给你的parser.

假设人的脚本叫/usr/bin/foo:

$ /usr/bin/foo --version
foo 1.0

下面的两个方法打印和获取version字符串:

OptionParser.print_version(file=None)

Print the version message for the current program (self.version) to file (default stdout). As with print_usage(), any occurrence of %prog in self.version is replaced with the name of the current program. Does nothing if self.version is empty or undefined.

OptionParser.get_version()

Same as print_version() but returns the version string instead of printing it.

 

 

15.5.2.8. optparse怎样处理错误

optparse 需要考虑两类错误: 程序员和用户错误. 程序员错误通常是错误地调用OptionParser.add_option(), e.g. 无效的 option字符串, 未定义的option属性, 丢失option属性, etc. 有两种方法来处理这些异常: 诱发一个异常(optparse.OptionError或者TypeError)或者使程序崩溃.

处理用户错误更加重要。optparse能够自动检查一些用户错误, 例如错误的bad option参数(passing -n 4x where -n takes an integer argument), 少写arguments (-n需要一个参数而没有写). 你也可以调用OptionParser.error()来发出一个程序自定义的错误条件:

(options, args) = parser.parse_args()
[...]
if options.a and options.b:
    parser.error("options -a and -b are mutually exclusive")

在各种情况下, optparse以相同的方式处理错误: 打印程序使用信息和错误信息到标准错误输出,并返回状态码2.

例如下面-n需要一个整数:

$ /usr/bin/foo -n 4x
Usage: foo [options]

foo: error: option -n: invalid integer value: '4x'

或者没有传递参数:

$ /usr/bin/foo -n
Usage: foo [options]

foo: error: -n option requires an argument

optparse自动产生的错误提示将具体的option包含其中; 保证自定义的OptionParser.error() 也是这样做的.

如果optparse缺省错误行为不符合你的需要, 你需要继承OptionParser并覆盖它的exit()error()方法.

15.5.2.9. 把上面的知识放到一起

一个完整的基于optparse的实例如下:

from optparse import OptionParser
[...]
def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename",
                      help="read data from FILENAME")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose")
    [...]
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")
    if options.verbose:
        print "reading %s..." % options.filename
    [...]

if __name__ == "__main__":
    main()

 

参考:

http://docs.python.org/library/optparse.html

posted @ 2013-04-03 15:09  业精于勤荒于嬉  阅读(345)  评论(0编辑  收藏  举报