欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python模块介绍- argparse:命令行选项及参数解析

程序员文章站 2022-06-07 14:18:20
python模块介绍- argparse:命令行选项及参数解析 2012-08-20磁针石 #承接软件自动化实施与等gtalk:ouyangchongwu#gmail.com...

python模块介绍- argparse:命令行选项及参数解析
2012-08-20磁针石

#承接软件自动化实施与等gtalk:ouyangchongwu#gmail.com qq 37391319 博客: http://blog.csdn.net/oychw

#版权所有,转载刊登请来函联系

#自动化测试和python群组: http://groups.google.com/group/automation_testing_python

#参考资料:《the python standard library by example》

#实验环境:python 2.7.3 centos release 6.2(final) 32bits

 

 

 

14.3 argparse:命令行选项及参数解析
作用:命令行选项及参数解析。

python版本:2.7及以后版本

argparse模块于python2.7引入,旨在替换optparse。

14.3.1建立解析器
import argparse

parser = argparse.argumentparser(

description=’this is a pymotw sample program’,

)      

argparse是一个完整的参数处理库。参数可以根据add_argument()的action选项触发不同action。支持的action有存储参数(单个,或作为列表的一部分);存储常量的值(对布尔开关true/false有特殊处理)。默认动作是存储参数值。支持type(指定存储类型)和dest(指定存储变量)等参数。

然后使用函数parse_args()进行参数解析,这个函数的输入默认是sys.argv[1:],也可以使用其他字符串列表。选项使用gnu/posix语法处理,可以混合选项和参数值。parse_args的返回值是一个包含命令参数的namespace。所有参数以属性的形式存在,比如args.myoption。

下面是一个简单的示例:

import argparse

 

parser = argparse.argumentparser(description='short sampleapp')

 

parser.add_argument('-a', action="store_true",default=false)

parser.add_argument('-b', action="store",dest="b")

parser.add_argument('-c', action="store",dest="c", type=int)

 

print parser.parse_args(['-a', '-bval', '-c', '3'])

    执行结果:

# pythonargparse_short.py

namespace(a=true, b='val', c=3)

 

长参数也可以进行同样处理:

import argparse

 

parser = argparse.argumentparser(

    description='examplewith long option names',

    )

 

parser.add_argument('--noarg', action="store_true",

                   default=false)

parser.add_argument('--witharg', action="store",

                   dest="witharg")

parser.add_argument('--witharg2', action="store",

                   dest="witharg2", type=int)

 

print parser.parse_args(

    [ '--noarg','--witharg', 'val', '--witharg2=3' ]

    )

    执行结果:

# python argparse_long.py

namespace(noarg=true, witharg='val', witharg2=3)

 

不同于optparse,argparse可以很好地处理非可选参数(没有’-‘等开头的参数):

import argparse

 

parser = argparse.argumentparser(

    description='examplewith nonoptional arguments',

    )

 

parser.add_argument('count', action="store",type=int)

parser.add_argument('units', action="store")

 

print parser.parse_args()

    没有指定类型的,默认是字符串。执行结果:

# python argparse_arguments.py 3inches

namespace(count=3, units='inches')

# python argparse_arguments.py some inches

usage: argparse_arguments.py [-h] count units

argparse_arguments.py: error: argument count: invalid intvalue: 'some'

# python argparse_arguments.py

usage: argparse_arguments.py [-h] count units

argparse_arguments.py: error: too few arguments

 

参数action有:

store:默认action模式,存储值到指定变量。

store_const:存储值在参数的const部分指定,多用于实现非布尔的命令行flag。

store_true / store_false:布尔开关。可以2个参数对应一个变量。

append:存储值到列表,该参数可以重复使用。

append_const:存储值到列表,存储值在参数的const部分指定。

version 输出版本信息然后退出。

下面是各种action的示例:

import argparse

 

parser = argparse.argumentparser()

 

parser.add_argument('-s', action='store',

                   dest='simple_value',

                    help='storea simple value')

 

parser.add_argument('-c', action='store_const',

                   dest='constant_value',

                   const='value-to-store',

                   help='store a constant value')

 

parser.add_argument('-t', action='store_true',

                   default=false,

                   dest='boolean_switch',

                   help='set a switch to true')

parser.add_argument('-f', action='store_false',

                   default=false,

                   dest='boolean_switch',

                   help='set a switch to false')

 

parser.add_argument('-a', action='append',

                   dest='collection',

                   default=[],

                   help='add repeated values to a list')

 

parser.add_argument('-a', action='append_const',

                   dest='const_collection',

                   const='value-1-to-append',

                   default=[],

                   help='add different values to list')

parser.add_argument('-b', action='append_const',

                    dest='const_collection',

                   const='value-2-to-append',

                   help='add different values to list')

 

parser.add_argument('--version', action='version',

                   version='%(prog)s 1.0')

 

results = parser.parse_args()

print 'simple_value    = %r' % results.simple_value

print 'constant_value  = %r' % results.constant_value

print 'boolean_switch  = %r' % results.boolean_switch

print 'collection      = %r' % results.collection

print 'const_collection = %r' % results.const_collection

    执行结果:

# python argparse_action.py -h

usage: argparse_action.py [-h] [-s simple_value] [-c] [-t][-f]

                         [-a collection] [-a] [-b] [--version]

 

optional arguments:

  -h, --help       show this help message and exit

  -s simple_value  store a simple value

  -c               store a constant value

  -t               set a switch to true

  -f               set a switch to false

  -a collection    add repeated values to a list

  -a               add different values to list

  -b               add different values to list

  --version        show program's version number and exit

# python argparse_action.py --version

argparse_action.py 1.0

# python argparse_action.py -s value

simple_value     ='value'

constant_value   = none

boolean_switch   = false

collection       = []

const_collection = []

# python argparse_action.py -c

simple_value     = none

constant_value   ='value-to-store'

boolean_switch   = false

collection       = []

const_collection = []

# python argparse_action.py -t

simple_value     = none

constant_value   = none

boolean_switch   = true

collection       = []

const_collection = []

# python argparse_action.py -f

simple_value     = none

constant_value   = none

boolean_switch   = false

collection       = []

const_collection = []

# python argparse_action.py -a one -a two -a three

simple_value     = none

constant_value   = none

boolean_switch   = false

collection       =['one', 'two', 'three']

const_collection = []

# python argparse_action.py -b -a

simple_value     = none

constant_value   = none

boolean_switch   = false

collection       = []

const_collection = ['value-2-to-append', 'value-1-to-append']

 

argumentparser函数中的选项prefix_chars可以指定前缀。默认使用unix风格,命令行使用‘-’作为前缀。可以使用windows的’/’或者其他符号。

import argparse

 

parser = argparse.argumentparser(

    description='changethe option prefix characters',

    prefix_chars='-+/',

    )

 

parser.add_argument('-a', action="store_false",

                   default=none,

                   help='turn a off',

                    )

parser.add_argument('+a', action="store_true",

                   default=none,

                   help='turn a on',

                    )

parser.add_argument('//noarg', '++noarg',

                   action="store_true",

                    default=false)

 

print parser.parse_args()

    执行结果:

root@szx-srv-automation argparse]# pythonargparse_prefix_chars.py -h

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]

 

change the option prefix characters

 

optional arguments:

  -h, --help        show this help message and exit

  -a                turn a off

  +a                turn a on

  //noarg, ++noarg

# python argparse_prefix_chars.py +a

namespace(a=true, noarg=false)

# python argparse_prefix_chars.py -a

namespace(a=false, noarg=false)

# python argparse_prefix_chars.py //noarg

namespace(a=none, noarg=true)

# python argparse_prefix_chars.py ++noarg

namespace(a=none, noarg=true)

# python argparse_prefix_chars.py --noarg

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]

argparse_prefix_chars.py: error: unrecognized arguments:--noarg

# python argparse_prefix_chars.py --noarg

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]

argparse_prefix_chars.py: error: unrecognized arguments:--noarg

 

处理配置文件中的参数:

mport argparse

from configparser import configparser

import shlex

 

parser = argparse.argumentparser(description='short sampleapp')

 

parser.add_argument('-a', action="store_true",default=false)

parser.add_argument('-b', action="store",dest="b")

parser.add_argument('-c', action="store",dest="c", type=int)

 

config = configparser()

config.read('argparse_with_shlex.ini')

config_value = config.get('cli', 'options')

print 'config  :',config_value

 

argument_list = shlex.split(config_value)

print 'arg list:', argument_list

 

print 'results :', parser.parse_args(argument_list)

    执行结果:

# python argparse_with_shlex.py

config  : -a -b 2

arg list: ['-a', '-b', '2']

results : namespace(a=true, b='2', c=none)

    其中ini文件的内容如下:

# vi argparse_with_shlex.ini

[cli]

options = -a -b 2

    上面例子使用了configparser来读取配置,再用shlex来切割参数。可以通过fromfile_prefix_chars 告知argparse输入参数为文件。

import argparse

#from configparser import configparser

#import shlex

 

parser = argparse.argumentparser(description='short sampleapp',

                                 fromfile_prefix_chars='@',

                                 )

 

parser.add_argument('-a', action="store_true",default=false)

parser.add_argument('-b', action="store",dest="b")

parser.add_argument('-c', action="store",dest="c", type=int)

 

print parser.parse_args(['@argparse_fromfile_prefix_chars.txt'])

    执行结果:

# python argparse_fromfile_prefix_chars.py

namespace(a=true, b='2', c=none)

    其中argparse_fromfile_prefix_chars.txt文件的内容如下:

# vi argparse_fromfile_prefix_chars.txt

-a

-b

2

 

14.3.2自动生成选项
argparse会自动生成的帮助和版本信息。argumentparser的add_help参数控制帮助的生成,默认是开启。

import argparse

parser = argparse.argumentparser(add_help=true)

parser.add_argument(’-a’, action="store_true",default=false)

parser.add_argument(’-b’, action="store",dest="b")

parser.add_argument(’-c’, action="store",dest="c", type=int)

print parser.parse_args()

下例就关闭帮助:

import argparse

parser = argparse.argumentparser(add_help=false)

parser.add_argument(’-a’, action="store_true",default=false)

parser.add_argument(’-b’, action="store",dest="b")

parser.add_argument(’-c’, action="store",dest="c", type=int)

print parser.parse_args()

执行结果:

$ python argparse_with_help.py -h

usage: argparse_with_help.py [-h] [-a] [-b b] [-c c]

optional arguments:

-h, --help show this help message and exit

-a

-b b

-c c

$ python argparse_without_help.py -h

usage: argparse_without_help.py [-a] [-b b] [-c c]

argparse_without_help.py: error: unrecognized arguments: -h

 

版本也可以进行类似的配置:

import argparse

parser = argparse.argumentparser(version=’1.0’)

parser.add_argument(’-a’, action="store_true",default=false)

parser.add_argument(’-b’, action="store",dest="b")

parser.add_argument(’-c’, action="store",dest="c", type=int)

print parser.parse_args()

print ’this is not printed’

执行结果:

$ python argparse_with_version.py -h

usage: argparse_with_version.py [-h] [-v] [-a] [-b b] [-c c]

optional arguments:

-h, --help show this help message and exit

-v, --version show program’s version number and exit

-a

-b b

-c c

$ python argparse_with_version.py -v

1.0

$ python argparse_with_version.py --version

1.0

14.3.3组织解析器
    公共解析器:通过父子类来实现。见argparse_parent_base.py:

import argparse

 

parser = argparse.argumentparser(add_help=false)

 

parser.add_argument('--user', action="store")

parser.add_argument('--password', action="store")

    子类:

import argparse

import argparse_parent_base

 

parser = argparse.argumentparser(

   parents=[argparse_parent_base.parser],

    )

 

parser.add_argument('--local-arg',

                   action="store_true",

                   default=false)

 

print parser.parse_args()

    注意:父类关闭了help。子类却默认开启了help。执行结果:

# python argparse_uses_parent.py -h

usage: argparse_uses_parent.py [-h] [--user user] [--passwordpassword]

                              [--local-arg]

 

optional arguments:

  -h, --help           show this help message and exit

  --user user

  --password password

  --local-arg

参数分组:默认有可选参数和必选参数组。前面的用户名和密码就可以分组:

argparse_parent_with_group.py

import argparse

parser = argparse.argumentparser(add_help=false)

group = parser.add_argument_group(’authentication’)

group.add_argument(’--user’, action="store")

group.add_argument(’--password’, action="store")

子类:

import argparse

import argparse_parent_with_group

 

parser = argparse.argumentparser(

   parents=[argparse_parent_with_group.parser],

    )

 

parser.add_argument('--local-arg',

                   action="store_true",

                   default=false)

 

print parser.parse_args()

执行结果:

# python argparse_uses_parent_with_group.py -h

usage: argparse_uses_parent_with_group.py [-h] [--user user]

                                         [--password password] [--local-arg]

 

optional arguments:

  -h, --help           show this help message and exit

  --local-arg

 

authentication:

  --user user

  --password password

使用add_mutually_exclusive_group()可以添加互斥选项:

import argparse

parser = argparse.argumentparser()

group = parser.add_mutually_exclusive_group()

group.add_argument(’-a’, action=’store_true’)

group.add_argument(’-b’, action=’store_true’)

print parser.parse_args()

执行结果:

# python argparse_mutually_exclusive.py -h

usage: argparse_mutually_exclusive.py [-h] [-a | -b]

 

optional arguments:

  -h, --help  show this help message and exit

  -a

  -b

# python argparse_mutually_exclusive.py -a

namespace(a=true, b=false)

# python argparse_mutually_exclusive.py -b

namespace(a=false, b=true)

# python argparse_mutually_exclusive.py -a -b

usage: argparse_mutually_exclusive.py [-h] [-a | -b]

argparse_mutually_exclusive.py: error: argument -b: notallowed with argument –a

嵌套解析:

import argparse

 

parser = argparse.argumentparser()

 

subparsers = parser.add_subparsers(help='commands')

 

# a list command

list_parser = subparsers.add_parser(

    'list', help='listcontents')

list_parser.add_argument(

    'dirname',action='store',

    help='directory tolist')

 

# a create command

create_parser = subparsers.add_parser(

    'create',help='create a directory')

create_parser.add_argument(

    'dirname',action='store',

    help='new directoryto create')

create_parser.add_argument(

    '--read-only',default=false, action='store_true',

    help='setpermissions to prevent writing to the directory',

    )

 

# a delete command

delete_parser = subparsers.add_parser(

    'delete',help='remove a directory')

delete_parser.add_argument(

    'dirname', action='store',help='the directory to remove')

delete_parser.add_argument(

    '--recursive', '-r',default=false, action='store_true',

    help='remove thecontents of the directory, too',

    )

 

print parser.parse_args()

执行结果:

# python argparse_subparsers.py -h

usage: argparse_subparsers.py [-h] {list,create,delete} ...

 

positional arguments:

 {list,create,delete}  commands

    list                list contents

    create              create a directory

    delete              remove a directory

 

optional arguments:

  -h, --help            show this help message and exit

# python argparse_subparsers.py create -h

usage: argparse_subparsers.py create [-h] [--read-only]dirname

 

positional arguments:

  dirname      new directory to create

 

optional arguments:

  -h, --help   show this help message and exit

  --read-only  set permissions to prevent writing to thedirectory

# python argparse_subparsers.py delete -r foo

namespace(dirname='foo', recursive=true)

14.3.4 高级参数处理
可变参数:数字n代表n的参数,?0或者1个参数。*0或者多个参数。+1或者多个参数。

import argparse

 

parser = argparse.argumentparser()

 

subparsers = parser.add_subparsers(help='commands')

 

# a list command

list_parser = subparsers.add_parser(

    'list', help='listcontents')

list_parser.add_argument(

    'dirname',action='store',

    help='directory tolist')

 

# a create command

create_parser = subparsers.add_parser(

    'create',help='create a directory')

create_parser.add_argument(

    'dirname',action='store',

    help='new directoryto create')

create_parser.add_argument(

    '--read-only',default=false, action='store_true',

    help='setpermissions to prevent writing to the directory',

    )

 

# a delete command

delete_parser = subparsers.add_parser(

    'delete',help='remove a directory')

delete_parser.add_argument(

    'dirname',action='store', help='the directory to remove')

delete_parser.add_argument(

    '--recursive', '-r',default=false, action='store_true',

    help='remove thecontents of the directory, too',

    )

 

print parser.parse_args()

执行结果:

# python argparse_nargs.py -h

usage: argparse_nargs.py [-h] [--three three three three]

                        [--optional [optional]] [--all [all [all ...]]]

                        [--one-or-more one_or_more [one_or_more ...]]

 

optional arguments:

  -h, --help            show this help message and exit

  --three three threethree

  --optional [optional]

  --all [all [all ...]]

  --one-or-moreone_or_more [one_or_more ...]

# python argparse_nargs.py

namespace(all=none, one_or_more=none, optional=none,three=none)

# python argparse_nargs.py --three

usage: argparse_nargs.py [-h] [--three three three three]

                        [--optional [optional]] [--all [all [all ...]]]

                        [--one-or-more one_or_more [one_or_more ...]]

argparse_nargs.py: error: argument --three: expected 3argument(s)

# python argparse_nargs.py --three a b c

namespace(all=none, one_or_more=none, optional=none,three=['a', 'b', 'c'])

# python argparse_nargs.py --optional

namespace(all=none, one_or_more=none, optional=none,three=none)

# python argparse_nargs.py --optional with_value

namespace(all=none, one_or_more=none, optional='with_value',three=none)

# python argparse_nargs.py --all with multiple values

namespace(all=['with', 'multiple', 'values'],one_or_more=none, optional=none, three=none)

# python argparse_nargs.py --one-or-more with_value

namespace(all=none, one_or_more=['with_value'], optional=none,three=none)

# python argparse_nargs.py --one-or-more

usage: argparse_nargs.py [-h] [--three three three three]

                        [--optional [optional]] [--all [all [all ...]]]

                        [--one-or-more one_or_more [one_or_more ...]]

argparse_nargs.py: error: argument --one-or-more: expected atleast one argument

参数类型:

importargparse

 

parser = argparse.argumentparser()

 

parser.add_argument('-i', type=int)

parser.add_argument('-f', type=float)

parser.add_argument('--file', type=file)

 

try:

    printparser.parse_args()

except ioerror, msg:

   parser.error(str(msg))

执行结果:

$ python argparse_type.py -i 1

namespace(f=none, file=none, i=1)

$ python argparse_type.py -f 3.14

namespace(f=3.14, file=none, i=none)

$ python argparse_type.py -i 1

namespace(f=none, file=none, i=1)

$ python argparse_type.py -f 3.14

namespace(f=3.14, file=none, i=none)

$ python argparse_type.py -i a

usage: argparse_type.py [-h] [-i i] [-f f] [--file file]

argparse_type.py: error: argument -i: invalid int value: ’a’

$ python argparse_type.py -f 3.14.15

usage: argparse_type.py [-h] [-i i] [-f f] [--file file]

argparse_type.py: error: argument -f: invalid float value:’3.14.15’

$ python argparse_type.py --file does_not_exist.txt

usage: argparse_type.py [-h] [-i i] [-f f] [--file file]

argparse_type.py: error: [errno 2] no such file or directory:

’does_not_exist.txt’

    choices可以指定参数的选项:

import argparse

 

parser = argparse.argumentparser()

 

parser.add_argument('--mode', choices=('read-only','read-write'))

 

print parser.parse_args()

执行结果:

 

# python argparse_choices.py -h

usage: argparse_choices.py [-h] [--mode{read-only,read-write}]

 

optional arguments:

  -h, --help            show this help message and exit

  --mode{read-only,read-write}

# python argparse_choices.py --mode read-only

namespace(mode='read-only')

# python argparse_choices.py --mode invalid

usage: argparse_choices.py [-h] [--mode{read-only,read-write}]

argparse_choices.py: error: argument --mode: invalid choice:'invalid' (choose from 'read-only', 'read-write')

argparse.filetype可以指定文件的模式和buffer:

import argparse

 

parser = argparse.argumentparser()

 

parser.add_argument('-i', metavar='in-file',

                   type=argparse.filetype('rt'))

parser.add_argument('-o', metavar='out-file',

                   type=argparse.filetype('wt'))

 

try:

    results =parser.parse_args()

    print 'input file:',results.i

    print 'outputfile:', results.o

except ioerror, msg:

   parser.error(str(msg))

执行结果:

# python argparse_filetype.py -h

usage: argparse_filetype.py [-h] [-i in-file] [-o out-file]

 

optional arguments:

  -h, --help   show this help message and exit

  -i in-file

  -o out-file

# python argparse_filetype.py -i argparse_filetype.py -otmp_file.txt

input file: <open file 'argparse_filetype.py', mode 'rt' at0xb75923e8>

output file: <open file 'tmp_file.txt', mode 'wt' at 0xb75926a8>

# python argparse_filetype.py -i no_such_file.txt

usage: argparse_filetype.py [-h] [-i in-file] [-o out-file]

argparse_filetype.py: error: argument -i: can't open'no_such_file.txt': [errno 2] no such file or directory: 'no_such_file.txt'

 

自定义action:

自定义action是argparse.action的子类可以处理add_argument中的参数定义相关的参数,并返回一个可调用对象。构造函数会处理参数定义,仅仅需要处理__call__函数。__call__函数中parser代表解释器,namespace用于返回解释结果,value为要处理的参数,option_string用于触发action(对可选参数,永远是none。

import argparse

 

class customaction(argparse.action):

    def __init__(self,

                option_strings,

                 dest,

                nargs=none,

                const=none,

                default=none,

                type=none,

                choices=none,

                required=false,

                help=none,

                metavar=none):

       argparse.action.__init__(self,

                                option_strings=option_strings,

                                 dest=dest,

                                 nargs=nargs,

                                 const=const,

                                default=default,

                                 type=type,

                                choices=choices,

                                required=required,

                                 help=help,

                                metavar=metavar,

                                 )

        print'initializing customaction'

        for name,valuein sorted(locals().items()):

            if name =='self' or value is none:

                continue

            print '  %s = %r' % (name, value)

        print

        return

 

    def __call__(self,parser, namespace, values,

                option_string=none):

        print'processing customaction for "%s"' % self.dest

        print ' parser = %s' % id(parser)

        print '  values = %r' % values

        print '  option_string = %r' % option_string

      

        # do somearbitrary processing of the input values

        ifisinstance(values, list):

            values = [v.upper() for v in values ]

        else:

            values =values.upper()

        # save theresults in the namespace using the destination

        # variable givento our constructor.

       setattr(namespace, self.dest, values)

        print

 

parser = argparse.argumentparser()

 

parser.add_argument('-a', action=customaction)

parser.add_argument('-m', nargs='*', action=customaction)

 

results = parser.parse_args(['-a', 'value',

                            '-m', 'multivalue',

                             'second'])

print results


执行结果:

# python argparse_custom_action.py

initializing customaction

  dest = 'a'

  option_strings =['-a']

  required = false

 

initializing customaction

  dest = 'm'

  nargs = '*'

  option_strings =['-m']

  required = false

 

processing customaction for "a"

  parser = 3076247052

  values = 'value'

  option_string = '-a'

 

processing customaction for "m"

  parser = 3076247052

  values =['multivalue', 'second']

  option_string = '-m'

 

namespace(a='value', m=['multivalue', 'second'])