python模块介绍- argparse:命令行选项及参数解析
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)
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)
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'])
推荐阅读