python argparse:命令行参数剖析详解
2019-11-18杂谈搜奇网56°c
A+ A-简介
本文引见的是argparse模块的基础运用要领,特别细致引见add_argument内建要领各个参数的运用及其效果。
本文翻译自argparse的官方申明,并加上一些笔者的明白
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
如上示例,argparse模块的基础运用包含5个步骤:
- import模块:import argparse
- 获剖析器对象:argparse.ArgumentParser
- 应用剖析器对象内建要领,增加参数剖析划定规矩:add_argument
- 应用剖析器对象内建要领,最先剖析参数,猎取剖析效果对象:parse_args
- 从剖析效果对象中,猎取参数值:parse_args
剖析器类(ArgumentParser)
在第2步中,我们经由过程ArgumentParser()
函数的挪用猎取了剖析器对象ArgumentParser
。
在相识剖析器对象的各个成员之前,我们先对一段一般的申明文本举行区间分别
# usage字段
usage: 递次名 [-h|--help] .....
# Description字段
递次功用形貌
# 位置参数申明(必选)
positional arguments:
...
# 可选参数申明
optional arguments:
...
# 补充申明字段
...
比方
usage: PROG [-h] [--foo [FOO]] bar [bar ...]
bar help
positional arguments:
bar bar help
optional arguments:
-h, --help show this help message and exit
--foo [FOO] foo help
And that's how you'd foo a bar
关于位置参数与可选参数的明白,参考下一章节:增加参数剖析划定规矩
在上述的区间划的熟悉下,我们再来看看剖析器对象的成员及其功用
名字 | 默许值 | 功用 |
---|---|---|
prog | sys.argv[0] | -h 时显现的递次名 |
usage | - | usage字段形貌 |
description | None | description字段形貌 |
epilog | None | 补充字段形貌 |
parents | None | 从父(大众)剖析器中继承一切的参数选项 |
formatter_class | None | 定制申明文本的显现作风 |
prefix_class | - | 定制前缀字符,比方前缀"-b"改成“+b" |
add_help | True | 是不是使能显现参数 -h --help |
allow_abbrev | True | 是不是支撑长参数 |
fromfile_prefix_chars | None | 略 |
argument_default | None | 略 |
conflict_handler | None | 略 |
比较经常使用的是description,比方:
parser = argparse.ArgumentParser(description='Process some integers.')
或许
parser = argparse.ArgumentParser()
parser.descritpioin="Process some integers."
增加参数剖析划定规矩(add_argument)
add_argument是剖析器类ArgumentParser的内建要领,用于向剖析器增加参数剖析划定规矩
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type]
[, choices][, required][, help][, metavar][, dest])
内建要领支撑以下的症结字,我们会对每一个症结字及其效果做进一步申明
症结字 | 简介 |
---|---|
name or flags | 参数名或许"-/--"开首的选项,比方foo 或许-f, --foo |
action | 婚配到选项后的行动 |
nargs | 选项追随的参数个数 |
const | 在某些action 和nargs 下,运用的固定值 |
default | 默许值 |
type | 参数范例 |
choices | 可选的参数值局限 |
required | 选项必选or可选 |
help | 参数形貌 |
metavar | 运用申明中显现的参数名 |
dest | 选项终究在剖析效果对象中的名字 |
症结字name or flags
症结字name是什么?flags又是什么?二者有什么差异?
name示意参数名,其赋值与位置递次相干,因而也叫位置参数名,敕令行中必需赋值
flags示意-|--
开首的参数名,敕令行中可选参数
比方:
#可选的flags参数
parser.add_argument('-f', '--foo')
#必选的name位置参数
parser.add_argument('bar0')
parser.add_argument('bar1')
这里假定--foo
须要带1个参数,那末
prog arg1 --foo arg2 arg3
- arg1 是位置参数bar0的值
- arg2 是可选参数'-f, --foo'的值
- arg3 是位置参数bar1的值
换句话来讲,在输入的敕令行中,撤除一切-|--
开首的参数及其带上的参数值以外,剩下的参数都为位置参数,其递次顺次对应运用add_argument注册的位置参数递次。
在敕令行挪用中,位置参数必需赋值,即每一个必选参数都要有赋值;而可选参数(-|--)
可根据需求挑选
症结字action
功用如其名,症结字action掌握婚配到敕令行选项后的行动。参数剖析后不是保留值就好了?我们继承看看。
症结字action只支撑以下值,我们稍后再细致解说每一个值的寄义:
值 | 寄义 |
---|---|
store | 保留参数值 |
store_const | 与症结字const合营运用,保留症结字const的值 |
store_true | 保留值为True |
store_false | 保留值为False |
append | 保留屡次选项值为列表 |
append_const | 与症结字const合营运用,保留症结字const的值为列表 |
const | 保留选项的涌现次数 |
help | 效果等效于-h 和 --help |
version | 打印版本 |
store
保留参数值,这也是默许的行动,我们看个例子:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
在parse_args()
以后,--foo
选项的值就保留到了parse_args()
的剖析效果对象中。
我们能够如许猎取剖析效果对象的值:
args = parser.parse_args('--foo 1'.split())
print(args.foo)
总结来讲,选项名成为了剖析效果对象的成员,而选项对应的值则成了成员的值
到这里,我们存在2个迷惑:
- 当同时支撑
-f
和--foo
时,生成的成员名是什么呢?能自定义名字么? - 当
PROG -f
如许不须要带参数的选项,存储的成员值是什么样的呢?
不必急,我们继承往下看
store_const
在婚配到选项后,存储症结字const的值,经常使用于敕令行中不带参数的选项。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)
从上面的例子,我们能够看到,在婚配到--foo
后,对应成员foo的保留为了const参数
的值。
但更多时刻,我们不带参数的选项更多只是示意布尔型的开关,这时刻我们可用store_true
或许store_false
store_true 和 store_false
store_true
和store_false
是一种特别的store_const
,存储的值范例为布尔型True
或False
。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)
示例中有3个布尔型“开关”,能够发明有以下特性:
store_true
在婚配到敕令选项后,保留为True
;相对的,store_false
保留为False
- 当敕令行中没婚配到开关后,比方示例中的
baz
,则保留为store_false
的相反值True
append
把一切值保留为一个列表,经常使用于支撑屡次选项的状况,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
append_const
与store_const
异常类似,只是把值存储为一个列表。此时假如没有指定症结字const,则默许为None
。append_const
经常使用于多个差别选项值须要存储到雷同成员列表的状况。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
明白上文须要晓得以下条件:
- 症结字dest用于指定成员名
- 参数的值能够是种种对象,包含范例对象,即示例中的str范例和int范例
在示例中,--str
的常量值是str范例,以列表情势保留到types成员;--int
的常量值是int范例,以列表情势保留到types成员
count
假如我们只须要统计选项涌现的次数,此处能够用count
,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count')
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
help
打印协助信息,功用等效于-h|--help
version
打印版本信息,须要合营症结字version运用,比方:
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0
症结字nargs
症结字nargs是number argumemts的缩写,示意选项有多少个参数,其支撑以下值:
值 | 寄义 |
---|---|
N (an integer) | 网络N个参数到列表 |
'?' | 无参数或单个参数 |
'*' | 大于即是0个参数 |
'+' | 大于即是1个参数 |
argparse.REMAINDER | 只网络不剖析 |
当没有指定症结字nargs时,其现实的值取决于症结字action,比方当action = "store"
时,默许猎取1个参数,当action = "store_true"
时,选项不须要带参数。
N (an integer)
此处的N
,示意一个整型数字,寄义为选项须要供应N个参数。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
>>> parser.add_argument('bar', nargs=1)
>>> parser.parse_args('c --foo a b'.split())
Namespace(bar=['c'], foo=['a', 'b'])
须要注重的是,当nargs = 1
时,其并不等效于症结字nargs的默许状况。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar0', nargs=1)
>>> parser.add_argument('bar1')
>>> parser.parse_args('a b'.split())
Namespace(bar0=['a'], bar1='b')
能够发明,nargs = 1
时,比方bar0,其值是一个列表,一个只要1个元素的列表;而默许状况下,就是一个元素,官方称为item
。
'?'
nargs='?'
能够完成3种场景:
- 输入的敕令行中,选项带参数时,值为附带的参数
- 输入的敕令行中,没有改选项时,值为症结字default的值
- 输入的敕令行中,有选项但没带参数时,值为症结字const的值(只适用于可选选项(flag))
比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
>>> parser.add_argument('bar', nargs='?', default='d')
>>> parser.parse_args(['XX', '--foo', 'YY'])
Namespace(bar='XX', foo='YY')
>>> parser.parse_args(['XX', '--foo'])
Namespace(bar='XX', foo='c')
>>> parser.parse_args([])
Namespace(bar='d', foo='d')
一个更经常使用的场景,是完成可选的输入输出文件,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
... default=sys.stdin)
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
... default=sys.stdout)
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
>>> parser.parse_args([])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
上述例子中,假如敕令行没有指定input,则运用规范输入stdin;假如敕令行没有指定output,则运用规范输出stdout
'*'
nargs=2
会限制肯定要有2个参数,假如须要恣意多个参数呢?我们能够用nargs='*'
,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
>>> parser.add_argument('--bar', nargs='*')
>>> parser.add_argument('baz', nargs='*')
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
与nargs=N
类似,终究的值是列表范例。
'+'
nargs='+'
与nargs='*'
从功用上异常类似,唯一差别的处所在于,nargs='+'
请求最少要有1个参数,不然会报错。
'?'
,'+'
与'*'
的定义与正则表达式中的?
,+
和*
异常类似
在正则表达式中,
- ?:示意0或1个字符
- +:示意大于即是1个字符
- *:示意大于即是0个字符
我们看个例子:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
>>> parser.parse_args(['a', 'b'])
Namespace(foo=['a', 'b'])
>>> parser.parse_args([])
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo
argparse.REMAINDER
nargs=argparse.REMAINDER
经常使用于网络参数后传递给其他的敕令行剖析东西,其不会剖析-|--
,只是网络一切选项到列表。
比方:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
上例中,argparse没有剖析args
选项的--arg1
,而是悉数网络到了一个列表
症结字const
在症结字acton和症结字nargs中,实在已触及了症结字const的一切功用。
症结字const只是存储一个常量值,在以下两种状况下才会运用:
action='store_const'
或许action='append_const'
nargs='?'
当运用action='store_const'
和action='append_const'
时,症结字const必需供应,对其他的action症结字时,默许值为None
症结字default
有时刻,选项不带参数,或许敕令行没对应选项,这时刻就能够运用默许值,而症结字default存储的就是默许值。默许状况下,症结字default的值为None
。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)
假如症结字default赋值的是字符串,而症结字type有指定参数范例,那末就会把字符串转为症结字type指定的范例,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
>>> parser.add_argument('--width', default=10.5, type=int)
>>> parser.parse_args()
Namespace(length=10, width=10.5)
假如症结字nargs为?
或许*
,那末default的值会在敕令行没有参数时运用,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)
症结字default也供应一种特别用法:default=argparse.SUPPRESS
。在这类状况下,假如敕令行并没有婚配的选项,那末并不会在剖析效果对象中增加选项对应的成员,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')
症结字type
默许状况下,argparse剖析的参数默许为字符串范例,固然也能够经由过程症结字type指定其他任何范例,比方float
,int
,以至是文件范例file
, 比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.add_argument('bar', type=open)
>>> parser.parse_args('2 temp.txt'.split())
Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)
假如症结字type指定的是文件范例,我们还能够经由过程```FileType('w')以可写情势翻开文件,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)
症结字type以至能指定为函数,经由函数处置惩罚后的返回值作为参数值,比方:
>>> def perfect_square(string):
... value = int(string)
... sqrt = math.sqrt(value)
... if sqrt != int(sqrt):
... msg = "%r is not a perfect square" % string
... raise argparse.ArgumentTypeError(msg)
... return value
...
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', type=perfect_square)
>>> parser.parse_args(['9'])
Namespace(foo=9)
>>> parser.parse_args(['7'])
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square
症结字choices
当我们须要限制选项的值局限,我们能够用症结字choices。症结字choices限制了参数值的可选列表,假如敕令行供应的参数值不在列表中,则会报错,比方:
>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')
固然,须要注重的是,症结字choice的值必需相符症结字type指定的范例。
症结字required
默许状况下,-f
和--foo
都是可选的,但假如须要改成必选,能够运用症结字required,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: argparse.py [-h] [--foo FOO]
argparse.py: error: option --foo is required
症结字help
症结字help是选项的申明,在-h
或许--help
时会显现出来,比方:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true',
... help='foo the bars before frobbling')
>>> parser.add_argument('bar', nargs='+',
... help='one of the bars to be frobbled')
>>> parser.parse_args(['-h'])
usage: frobble [-h] [--foo] bar [bar ...]
positional arguments:
bar one of the bars to be frobbled
optional arguments:
-h, --help show this help message and exit
--foo foo the bars before frobbling
固然,症结字help也支撑花样化显现,%(prog)s
和大部分add_argument()的症结字,包含%(default)s
,%(type)s
,等等,比方:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42,
... help='the bar to %(prog)s (default: %(default)s)')
>>> parser.print_help()
usage: frobble [-h] [bar]
positional arguments:
bar the bar to frobble (default: 42)
optional arguments:
-h, --help show this help message and exit
花样为%(keyword)s
,假如须要显现%
,就须要运用%%
还存在一种特别状况,假定我们不愿望参数显现在--help中,我们能够用:argparse.SUPPRESS,比方:
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
>>> parser.print_help()
usage: frobble [-h]
optional arguments:
-h, --help show this help message and exit
症结字dest
argparse会把剖析的效果保留成剖析效果对象的属性,然则,属性名是什么呢?比方,parser.add_argument(’-f', '--foo')
,剖析效果是保留在属性f
中照样foo
中?症结字dest就是用于定制属性名的。
我们先相识默许状况下,属性名是什么?
对位置参数而言,症结字dest默许为第一个参数名,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')
对可选参数而言,症结字dest首选第一个涌现的长参数名。假如没有长参数,则挑选第一个短参数名。不论挑选的是长参数照样短参数,都会把-|---
给去掉,同时把名字中的-
标记替换为_
,以相符python的变量定名划定规矩,比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')
我们再看看,假如定制属性名有什么效果?
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')
症结字metavar
在实行-h|--help
,显现的协助信息中,怎样定制选项带的参数名呢?比方:
-t T loop times
我愿望修正显现的T
为TIMES
,更直观。这时刻我们就能够运用症结字metavar了。
在默许状况下,对位置参数,则会直接显现参数名,对可选参数,则会转为大写。比方:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage: [-h] [--foo FOO] bar
positional arguments:
bar
optional arguments:
-h, --help show this help message and exit
--foo FOO
上例中,位置参数bar直接显现为bar,而可选参数--foo带的参数名就转大写显现FOO。
假如我们定制显现的参数名,该怎么做呢?
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage: [-h] [--foo YYY] XXX
positional arguments:
XXX
optional arguments:
-h, --help show this help message and exit
--foo YYY
固然,还存在一种特别状况,就是有多个参数nargs=N
,这时刻症结字metavar能够以列表情势供应啦,比方:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', nargs=2)
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> parser.print_help()
usage: PROG [-h] [-x X X] [--foo bar baz]
optional arguments:
-h, --help show this help message and exit
-x X X
--foo bar baz
末了,有一点要注重的时,症结字metavar与症结字dest不一样的处所在于,症结字metavar仅仅只影响-h|--help的显现效果,症结dest则同时影响剖析效果属性名
猎取剖析效果
在action='store'中提到:选项名成为了剖析效果对象的成员,而选项对应的值则成了成员的值,所以假如我们须要猎取剖析后的效果,直接运用剖析效果的成员值就好了。比方:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', dest='xyz')
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> args = parser.parse_args("--foo a b -x c".split())
>>> print(args.foo)
>>> ['a', 'b']
>>> print(args.xyz)
>>> c