深入理解python命令行解析模块optparse(optparse源代码解读)

optparse是python用来解析命令行参数的,最早是getopt,option比getopt更强大和灵活。最新的命令行解析使用argparse,因此optparse今后将不会再被开发,optparse在python的源代码位置是Lib/optparse.py。

optparse.py模块主要类结构简介

optparse里面包含了几个主要的类:OptionParser解析类、Option定义类、Values解析结果类。OptionParse是入口,实例化OptionParse类的时候可以通过option_list指定option定义列表,version作为版本管理,另外OptionParse默认会添加一个-h/–help的option,用来打印命令行帮组列表。通过add_option方法可以动态的添加一个option,即实例化一个Option类。Option类里面会定义一些属性用来管理各种负责的命令行参数,具体可以看下面option定义的分析。通过parse_args方法可以解析命令行参数,如何解析可以看下面option的解析,解析结果保存在一个Values解析类实例中。下面可以看一个简单的例子:

from optparse import OptionParser 
parser = OptionParser() 
parser.add_option(“-f”, “–file”, action=”store”, type=string”, dest=”filename”) 
args=[“-f”, “./foo.txt”] 
(values,args) = parse.parse_args(args) 
print values.filename 
foo.txt 
  • 接下来分两大类来解析上面这个例子

option定义

add_options的原型是 
def add_option(self, args, *kwargs) 
在调用add_option的时候该如何写好args和kwargs呢?

1. args类的参数是不带key值的,比如-f, –file 
2. kwargs类是带key的,比如action=”store” 

注意:这里必须严格遵循这个规则,Option类会把args当作option选项来解析,把kwargs会被当作option选项的属性来解析。接下里看下Option如何解析args和kwargs

接下来看下option是如何解析这两类定义option的参数

args解析

定义规则

1. 如果是两个字符的,则必须是一个 - 开头,定义为short_opts,比如:-f
2. 如果是多于两个字符的,必须是 – 开头,定义我long_pots,比如:–filename 

kwargs解析

上面有说到kwargs会作为option的属性,option的支持的属性列表就是kwargs支持的key列表,因此kwargs支持的key列表如下:ATTRS =[‘action’,’type’,‘dest’,’default’,’nargs’,’const’,’choices’,’callback’,’callback_args’,’callback_kwargs’,’help’,’metavar’] 
这些key都会作为option实例的属性,而这些属性的作用是控制命令行类型和命令行解析的,各种各样的命令行类型都是通过这些属性来配合定义的。在解析的时候,会依据命令行的aciton来对实际的参数值做不同的处理,具体在下面解析类分析的时候会详细介绍。这些属性是如何配合组合各种各样的命令接口的,可以查考下面的一串属性检查函数来控制:

  1. action属性检查

    如果aciton=None,则acton默认为store 
    action支持的类型列表: 
    ACTIONS = (“store”,”store_const”,”store_true”, “store_false”,”append”,append_const”,”count”,”callback”,”help”,”version”)

  2. type属性检查

    type的支持类型列表:TYPES = (“string”, “int”, “long”, “float”, “complex”, “choice”),其中string可以用str代替。如果Type为None,并且action是[“store”, “append”],这时候如果choices不为None,则type=choice,否则为type=string.如果type不为None,则action是["store","append","callback"]。反过来就是说这些action才支持type属性。比如下面定义就会出错 
    parser.add_option("-v", "–verbose", action="count",dest="verbosity",type="int")

  3. choice属性检查

    如果choices不为None,则type必须是choice类型,反过来,如果type=choice,则choices必须不为None,而且choice必须是元组或者列表

  4. dest属性检查

    dest属性的值会作为Values属性里面option实例的名称,比如上面例子的values.filename,这个filename就是dest传递进去的。如果dest=None,这时候如果action在STORE_ACTIONS = ("store","store_const","store_true","store_false","append","append_const","count")里面或者type不为None的时候,dest会从args里面解析,也就是从上面的short_opt和long_opt里面解析:

    • long类型的opts:去掉–,把-转成_比如--filename > filename --foo-bar > foo_bar2)
    • short类型:去掉-,取后面的字符比如-f > f
  5. const属性检查

    const属性是为了固定某些参数的值而设定的。const属性只支持action=["store_const"、"append_const"]

  6. nargs属性检查

    如果nargs不为None,则action=["store","append","callback"]。反过来如果action在这些类型里面,而nargs=None,则nargs会默认设置为1

  7. callback属性检查

    如果action="callback",则callback属性一个可调用的(具有call方法)属性,并且callback_args属性是元组类型,callback_kwargs属性是字典类型,当然这两个都不是必须参数。反过来,如果callback、callback_args、callback_kwargs其中的某任何一个属性不为None,则action必须是”callback”。

option解析

解析函数原型

def parse_args(self, args=None, values=None)
  • args:是一个列表参数,默认是sys.argv[1:]
  • values:是optparse的Values对象,包含所有parse所添加的option values,之所以放这个参数是因为option可以被parse_args会多次被解析,这样就可以随时更新option的值
  • 返回值:所有结果过后的option对象(在optparse.py里面是Values对象)和剩余没有解析出来的args

    1. values

      如果values=None,则会根据定义每个option实例的时候给定的default属性的值来生成一个Values对象,如果option没有给定default,则就为空,比如上面例子,得出来得values实例就是: 
      < Values at 0x1044bc5a8: {'filename': None}> 
      如果是 
      parser.add_option("-f", "--file", action="store", type="string", dest="filename",default="test.yml") 
      则value实例就是: 
      < Values at 0x1044bc5a8:: {'filename': 'test.yml'}>

    2. 处理参数

      处理参数会根据 - 和 -- 分为short_opt和long_opt处理,两个处理大差不差,以short_opt为例子 
      short_opt处理

      • 取出opt实例和opt的value,对value值进行type检查
      • 依据opt实例的action处理其对应的value值
    3. 处理函数

      处理函数原型如下: 
      take_action(self, action, dest, opt, value, values, parser)

      • action用来区分不同的处理逻辑
      • dest用来更新values实例里面的option实例
      • opt作为callback方法的参数values代表这个opt的值
      • values是最终要返回回去的values实例
      • parse的作用: 1、用来作为callback类型action的方法的参数. 2、打印命令行帮助和版本信息
    4. action处理

      具体每个不同的action的处理逻辑

      • store:直接更新option值:setattr(values, dest, value)
      • store_const:取该添加改option的时候给定的const属性:setattr(values, dest, self.const)
      • store_true:将option的值设置为True值:setattr(values, dest, True)
      • store_false:将option的值设置为False:setattr(values, dest, False)
      • append:将value值追加给option:values.ensure_value(dest, []).append(value)
      • append_const:追加const的值给option:values.ensure_value(dest, []).append(self.const)
      • count:统计次数给option:setattr(values, dest, values.ensure_value(dest, 0) + 1)
      • callback:取出callback_args和callback_kwargs,并调用callback方法,具体处理逻辑看自己写的callback方法 
        args = self.callback_args or () 
        kwargs = self.callback_kwargs or {} 
        self.callback(self, opt, value, parser, *args, **kwargs)
      • help:打印option的帮助文档,会打印所有已经添加给当前parse实例的option 
        parser.print_help() 
        parser.exit()
      • version:打印自己定义的版本号,这里要求使用在实例化OptionParse对象的时候指定vaersion=”124” 
        parser.print_version() 
        parser.exit()

OptionParse不止只有add_option和parse_args两个方法,还支持比如批量添加option的add_options,支持option组的add_option_group等等,了解了大概的处理流程,其他的可以执行查阅源码。

附上几个简单的例子

#!/usr/bin/python
#  Filename: optparse-test.py
#   Created: 2016-12-01 21:41:41
#      Desc: TODO (some description)
#    Author: linbing, [email protected]
#   Company: t2cloud

from optparse import OptionParser
def callbacktest(option, opt, value, parse):
    print "-----callback test----"

# parser = OptionParser(version="10.10")
parser = OptionParser(version="112")
# parser = OptionParser()
parser.add_option("-f", "--file", type="string",dest="filename",default="test.yml")
# parser.add_option("-f", "--file", action="store", type="string",dest="filename",default="test.yml")
# parser.add_option("-v", "--verbose", action="count",dest="verbosity",type="int")
parser.add_option("-v", "--verbose", action="count",dest="verbosity")
parser.add_option("-s", "--store_const", action="store_const", dest="const", const="jbjb")
parser.add_option("-c", "--callback", action="callback",dest="call",callback=test, type=str)
parser.add_option("-a", "--append", action="append", dest="append")

# args = ["-f", "foo.txt", "-vvv","-v", "-s", "lb", "-c", "./test.yml", "-a" "bb=cc", "-a", "cc=dd"]
# args  = ["-h"]
# args  = ["--version"]
(options, args) = parser.parse_args(args)
print options.filename
print options.verbosity
print options.const
print options.append
print '----- args ----'
print args

具体命令行的使用可以参考python官方文档 
https://docs.python.org/2/library/optparse.html

猜你喜欢

转载自blog.csdn.net/ebzxw/article/details/80309252
今日推荐