Python命令行工具开发之二:使用optparse模块编写命令行工具

简介

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"选项(将触发额外输出)。
#/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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值