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()
你的脚本用户能够在命令行做如下操作:
--file=outfile -q
optparse基于用户输入的命令行值,通过调用parse_args() 函数来设置options对象的属性。当parse_args() 函数返回后,
options.filename会是"outfile",options.verbose会是False. optparse 支持长和短选项,允许短选项合并,允许选项和它们的参数以多种不同方式关联。因此,下面的命令行输入是等价的:
-f outfile --quiet
--quiet --file outfile
-q -foutfile
-qfoutfile
另外,用户能够通过下面的命令行来获取帮助
-h
--help
optparse会打印出你脚本选项的简短概述:
Usage: [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]).
optparse被设计用于鼓励以传统的命令行接口来创建应用程序。它只支持在Unix下使用的最通用的命令行语义和语法。
命令行上输入的字符串,被shell传递给execl() or execv()。在python中,参数是sys.argv[1:] (sys.argv[0]是被执行程序的名字)。Unix shells也使用术语"word"。
它用于取代参数列表。这里的参数列表不仅仅是sys.argv[1:],也可能是另一些列表形式。因此你应该把argument当作sys.argv[1:]的一个元素或者其它列表的一个元素。
一个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会被此选项所使用。使用optparse, option arguments 可以和option分离:
-f foo
--file foo
也可以和option合并在一起:
-ffoo
--file=foo
一个选项要么带argument要么不带. 许多人想要“optional option arguments(可选的选项参数)” 功能,这意味着选项可以带参数也可以不带。这有些争议,因为它会使解析发生歧义:如果-a和-b的参数都是可选的,那我们如何解析-ab? 因为歧义, optparse 不支持这一功能.
例如:
prog -v --report /tmp/report.txt foo bar
-v and --report是options. 假设--report带一个参数, /tmp/report.txt是option argument. foo和bar是positional arguments.
Options被用于提供信息来自定义程序的执行。选项通常是可选的.一个程序应该能够在没有options时也能运行。
Positional arguments是你的应用程序运行绝对需要的信息。
一个好的用户接口应该尽可能有少的绝对需求。当你的应用程序有太多信息需要提供,很多人会选择放弃。
总之,尽可能减少用户需要提供绝对信息的数量。灵活性和复杂性是相对的,越灵活越复杂,需要在灵活性和复杂性之间做出权衡。越灵活也越难维护。
因为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() 返回两个值:
本教程只覆盖以下四个重要的option属性: action, type, dest (destination), and help. 其中, action是最基本的.
Actions告诉optparse在命令行碰到一个option时做什么。有一个固定的actions集合硬编码到optparse;增加新的actions是一个高级课题,它在Extending optparse有介绍. 大多数的actions告诉optparse在某个变量中存储值,—例如, 从命令行获取一个字符串,然后存储在options的属性中。
如果你没有指定option action,optparse缺省是store.
最常用的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也包含内建的long和complex类型. Adding types is covered in section Extending optparse.
标识options—设置一个变量为true或false.optparse有两个独立的actions来支持这个特性, store_true和store_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为真;碰到-q, options.verbose设置为假.
Some other actions supported by optparse are:
These are covered in section Reference Guide, Reference Guide and section Option Callbacks.
以上的例子都是将碰到某个option时,设置某个值。如果没有碰到这些option呢。因为我们未提供缺省值,他们都会被设置为None。这通常是合理的,但是有时你想要更多的控制。optparse让你为各个目标提供缺省值,在命令行在解析前就会被赋予这些值.
首先,考虑verbose/quiet例子. 如果我们想要optparsed在没有碰到-q时设置verbose为True:
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: 目标会使用最后计算的缺省值.
一个指定目标缺省值更清晰的方式是OptionParser的set_defaults()方法,在调用parse_args()之前调用此方法:
parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()
尽量不要使用两种方式来设置缺省值,以免混乱。
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: [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.
如果有许多options,把这些option分组为获得更好的帮助信息.一个OptionParser能够包含多个option组,每个组包含多个options.
一个option组通过使用类OptionGroup获得:
where
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: [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: [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:
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.
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字符串:
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.
Same as print_version() but returns the version string instead of printing it.
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()方法.
一个完整的基于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