简介
Python标准库的optparse模块,有一个非常好的选项解析功能,来处理创建一个高质量的命令行工具相关复杂事务,进行高质量的命令行工具开发。尽管该模块从Python 2.7版本已经被argparse替代,但现存代码中仍有大量基于optparse模块的实现,需要了解这个模块的使用方法。本文将简要介绍optparse模块的各种使用模式,以快速掌握该模块的使用方法。
非选项使用模式
非选项模式是optparse的简单使用模式,尽管没有选项,但是仍然发挥了optparse的长处。
#!/usr/bin/env python
'''
Created on May 17, 2017
@author: bob
'''
import optparse
import os
def main():
p = optparse.OptionParser(description="Python 'ls' command clone",
prog="pyls", version="0.1a",
usage="%prog [directory]")
options, arguments = p.parse_args()
#check the argument number, only accept one argument
if len(arguments) == 1:
path = arguments[0]
for filename in os.listdir(path):
print filename
else:
#print help information
p.print_help()
if __name__ == '__main__':
main()
在这个例子中,通过Python实现了ls命令,并接受一个参数,指定执行pyls.py命令的路径。尽管并没有使用选项功能,但是仍然可以通过optparse来处理程序流。
在创建OptionParser实例时,并不要求提供输入参数,但用户可以根据自己的需要来提供输入参数,定制OptionParser实例。OptionParser常用的参数使用方法如下:
usage: 缺省为"%prog [options]"。该值用于指导用户如何使用该程序。
version: 显示程序版本信息
description: 提供如何使用该程序的文本描述信息
prog: 提供扩展usage和version选项里%prog参数
parse_args()函数方法用于解析命令行参数,并返回(options, args)元组数据,其中options存储返回的输入选项的解析数据,args为所有已经被处理的选项后的剩余位置参数。
脚本执行结果:
bob@ubuntu:~/workspace/PythonStudy/clis$ ./pyls.py
Usage: pyls [directory]
Python 'ls' command clone
Options:
--version show program's version number and exit
-h, --help show this help message and exit
bob@ubuntu:~/workspace/PythonStudy/clis$ ./pyls.py .
pyls.py
__init__.py
sysargv.py
hello_world_optparser.py
hello_world_optparse1.py
True/False使用模式
在程序中使用一个选项来设置True或False是非常有帮助的。这其中的典型示例涉及设置"--quite"选项(该参数关闭所有标准输出)和"--verbose"选项(将触发额外输出)。
这是在optparse中有关使用True/False选项最为精华的内容。
#/usr/bin/python
# -*- coding: UTF-8 -*-
'''
Created on 2017年5月28日
@author: bob
'''
import optparse
import os
def main():
p = optparse.OptionParser(description="Python 'ls' command clone", prog="pyls",
version="0.1a", usage="%prog [directory]")
p.add_option("--verbose", "-v", action="store_true",
help="Enables verbose output", dest="verbose", default=True)
p.add_option("--quiet", "-q", action="store_false",
help="Disables verbose output", dest="verbose")
options, arguments = p.parse_args()
if len(arguments) == 1:
if options.verbose:
print "Verbose mode enabled"
path = arguments[0]
for filename in os.listdir(path):
if options.verbose:
print "Filename: %s" % filename
else:
print filename
else:
p.print_help()
if __name__ == '__main__':
main()
当用户设置了"--verbose"和"--quiet"选项,并同时将dest设置为verbose。但两者的action和default并不相同:其中"--verbose"选项的action设置为"store_true", default设置为True;"--quiet"选项的action设置为"store_false", 使用缺省的default值None。这样,用户如果不提供选项或-v选项时,使能详细输出;否则,禁用详细输出功能。
这是在optparse中有关使用True/False选项最为精华的内容。
计数选项使用模式
在典型的Unix命令行工具中,如tcpdump,如果你指定了-vvv,相比于仅使用-v或-vv将获得更多的详细信息的输出。可以让optparse做同样的事情,通过添加一个计数器,对每次指定的选项计数。
#/usr/bin/python
# -*- coding: UTF-8 -*-
'''
Created on 2017��528日
@author: bob
'''
import optparse
import os
def main():
p = optparse.OptionParser(description="Python 'ls' command clone",
prog="pyls", version="0.1a",
usage="%prog [directory]")
p.add_option("-v", action="count", dest="verbose")
options, arguments = p.parse_args()
if len(arguments) == 1:
if options.verbose:
print "Verbose mode enable at level: %s" % options.verbose
path = arguments[0]
for filename in os.listdir(path):
if options.verbose == 1:
print filename
elif options.verbose == 2:
print "Filename: %s" % filename
else:
fullpath = os.path.join(path, filename)
print "Filename: %s | Byte Size: %s" % (filename, os.path.getsize(fullpath))
else:
p.print_help()
if __name__ == '__main__':
main()
通过使用一个自动增加计数的设计模式,可以确保仅一个选项,却可以做三件不同的事情。用户在执行该脚本时,可以使用-v, -vv, -vvv选项来显示不同的文件信息。
选项使用模式
有时展示选项的一些选择是比较容易的。在上面的例子中,可以创建选项的"--verbose"和"--quiet",可以让其从"--chatty"选择的结果中进行选择。
#/usr/bin/python
# -*- coding: UTF-8 -*-
'''
Created on 2017��5��29��
@author: bob
'''
import optparse
import os
def main():
p = optparse.OptionParser(description="Python 'ls' command clone",
prog="pyls",
version="0.1a",
usage="%prog [directory]")
p.add_option("--chatty", "-c", action="store", type="choice",
dest="chatty",
choices=["normal", "verbose", "quiet"],
default="normal")
options, arguments = p.parse_args()
print options
if len(arguments) == 1:
if options.chatty == "verbose":
print "Verbose mode enabled"
path = arguments[0]
for filename in os.listdir(path):
if options.chatty == "verbose":
print "Filename: %s " % filename
elif options.chatty == "quiet":
pass
else:
print filename
else:
p.print_help()
if __name__ == '__main__':
main()
在该例子中,-c选项仅接受normal、verbose、quiet选项,如果输入选项错误,optparse模块将输出错误提示信息。
多参数的选项使用模式
默认情况下,一个optparse选项只能有一个参数,但是可以指定参数的个数。如果nargs参数大于1,命令行需要提供多个参数,并且所有的参数都会按照type类型进行转换,并以元组的形式存储在dest中。实际的例子如下:
#/usr/bin/python
# -*- coding: UTF-8 -*-
'''
Created on 2017��5��29��
@author: bob
'''
import optparse
import os
def main():
p = optparse.OptionParser(description="Lists content of two directories",
prog="pymultils",
version="0.1a",
usage="%prog [--dir dir1 dir2]")
p.add_option("--dir", action="store", dest="dir", nargs=2)
options, arguments = p.parse_args()
if options.dir:
for dir in options.dir:
print "Listing of %s\n" % dir
for filename in os.listdir(dir):
print " %s" % filename
else:
p.print_help()
if __name__ == '__main__':
main()
组选项使用模式
当需要处理很多选项时,可以对选项进行分组以更好的输出帮助信息。一个OptionParse对象可以包含几个选项组,每个选项组可以包含几个选项。这并不影响选项的解析,仅为了更好的对帮助信息分类,方便用户使用。#/usr/bin/python
# -*- coding: UTF-8 -*-
'''
Created on 2017��5��29��
@author: bob
'''
from optparse import OptionParser, OptionGroup
def main():
usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage, version="0.1a")
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]")
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)
(options, args) = parser.parse_args()
print options
print args
if __name__ == '__main__':
main()
命令的帮助信息显示如下:
Usage: test_optparse.py [options] arg1 arg2
Options:
--version show program's version number and exit
-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
总结
本文介绍了optparse常见的集中使用模式,可以快速帮助读者写出高质量的命令行工具。但很多细节的内容,仍需要在使用的过程中参考编程手册。
参考资料
1. Python for UNIX and Linux System Administration
2. Python Manual 2.7.13