本文主要介绍python标准库中推荐的命令行解析模块argparse。
本文主要针对 Python 3. 所以和python 2.x会有一些细节上的差异, 特别对于一些在python 3.x中得到改进的exception消息方面.
本文收录在我的博客,欢迎访问: http://www.sskywatcher.com/blog/
Note
还有两个类似功能的模块, 分别是getopt
(类似C语言中的getopt()
) 和optparse
。其实argparse
是基于optparse
, 所以这两个模块的用法很相似。
概念
我们首先用LS命令做一个实例,来看一下本中即将介绍的一系列功能:
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
$ ls pypy
ctypes_configure demo dotviewer include lib_pypy lib-python ...
$ ls -l
total 20
drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
drwxr-xr-x 4 wena wena 4096 Feb 8 12:04 devguide
-rwxr-xr-x 1 wena wena 535 Feb 19 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Feb 7 00:59 pypy
-rw-r--r-- 1 wena wena 741 Feb 18 01:01 rm-unused-function.patch
$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...
以上四个命令中我们可以了解一些概念:
- ls没有任何参数时,ls命令依然可以发挥作用。 I默认显示该目录中所有上下文。
- 如果想让ls干一些超出默认功能的活,那么必须给ls更新的信息。比如我想让他显示一个其他目录
pypy
。只需要指定一个位置参数(position argument)。之所以叫位置参数是纯粹根据他在命令行中出现的位置,程序即可知道怎么处理这个参数。在一些其他的命令中这话中阐述具有更加重大的意义,比如cp, 它的基本用法即为:cp SRC DEST
。第一个参数表示你想拷贝的,第二个位置参数指定你需要拷贝到哪里去。 - 我们让系统显示每个文件的更多信息,而不是仅仅列出文件名。
-l
参数被称为一个可选参数(optional argument)。 - 这是帮助信息的片段节选.。当你偶然遇到一个以前从未用过的程序时这非常有用, 通过阅读帮助即可简单了解这个程序如何工作。
基础用法
首先来一个基本不做任何事情的实例:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
执行结果:
$ python prog.py
$ python prog.py --help
usage: prog.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
$ python prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo
Here is what is happening:
- 不带任何参数执行这个脚本时,标准输出没有任何内容。
第二个命令即可发现argparse
的一些用处。即什么都不用做,即可让你获得一个漂亮的帮助界面--help
选项, 也可用用段选项-h
, 是唯一一个不需要做任何代码即可实现的功能。指定任何其他的参数执行该脚本都会报错。
位置参数(Positional arguments)
例子:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo
执行结果:
$ python prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
$ python prog.py --help
usage: prog.py [-h] echo
positional arguments:
echo
optional arguments:
-h, --help show this help message and exit
$ python prog.py foo
foo
解释一下:
add_argument()
指定该命令行将会接受的参数。 这里指定了一个参数名为echo
。- 执行该程序将会需要指定一个参数。
parse_args()
方法会精确返回参数的值, 此例中即返回echo。
- 这是一个
argparse
内建支持的‘magic’类型变量(i.e. 无需指定变量来存储参数值)。你应该注意到 参数的名字 matches the string argument given to the method,echo
.
修改help信息使其更有用:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print args.echo
执行结果:
$ python prog.py -h
usage: prog.py [-h] echo
positional arguments:
echo echo the string you use here
optional arguments:
-h, --help show this help message and exit
尝试一些更有用的操作:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
print args.square**2
执行结果出错了!
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 5, in <module>
print args.square**2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
argparse
将会默认将参数传来的值作为strings处理, 除非我们指定它作为其他类型。接下来使用 argparse
将参数值作为int类型处理:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number",
type=int)
args = parser.parse_args()
print args.square**2
执行结果:
$ python prog.py 4
16
$ python prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'
OK!
可选参数(Optional arguments)
接下来看看如何添加一个可选参数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
print "verbosity turned on"
执行结果:
$ python prog.py --verbosity 1
verbosity turned on
$ python prog.py
$ python prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
optional arguments:
-h, --help show this help message and exit
--verbosity VERBOSITY
increase output verbosity
$ python prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument
解释一下:
- 这么编写程序是为了让他在指定
--verbosity
参数显示一些信息,没有指定时则不显示。 - 即使没加这个参数也可以执行这个程序并没有任何报错,可以确定这确实一个可选参数。默认情况下,当一个可选参数没有被使用时, 他的相关变量
args.verbosity
,将会使用None
作为值,从代码中if
语句判断的结果我们可以得出该结论。 - 注意帮助信息的变化。
- 使用
--verbosity
选项时, 你必须指定一个任意值。
上面例子中参数--verbosity
接受任意值,但是实际中我们只接受两个可用的参数值,比如True
or False。
可以如下修改代码:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
执行结果:
$ python prog.py --verbose
verbosity turned on
$ python prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1
$ python prog.py --help
usage: prog.py [-h] [--verbose]
optional arguments:
-h, --help show this help message and exit
--verbose increase output verbosity
- 这个选项相对于参数来说更像一个flag。 应该是用一个更贴近这种性质的参数名,比如
action,并
将其设置为"store_true"。
这么做的后果是:当你写带该参数,那么将会将args.verbose赋值为
. 反之则赋值为True
False
. - 注意帮助信息的变化。
短选项(short options)
例子:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
执行结果:
$ python prog.py -v
verbosity turned on
$ python prog.py --help
usage: prog.py [-h] [-v]
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
以上实现了同时指定 长选项名和短选项名。
结合位置参数和可选参数
我们的示例程序的复杂度进一步提升了:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print "the square of {} equals {}".format(args.square, answer)
else:
print answer
来看一看执行结果:
$ python prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
$ python prog.py 4
16
$ python prog.py 4 --verbose
the square of 4 equals 16
$ python prog.py --verbose 4
the square of 4 equals 16
- 以上程序指定了一个位置参数,一个可选参数。
- 执行命令时参数的顺序不影响。
下来我们赋予程序拥有多种详细值得能力:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行一下:
$ python prog.py 4
16
$ python prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
$ python prog.py 4 -v 1
4^2 == 16
$ python prog.py 4 -v 2
the square of 4 equals 16
$ python prog.py 4 -v 3
16
注意下当-v的值为3的时候, 这是程序的一个bug。如何让改善呢?现在我们通过add_argument()方法的choices入参来限制参数可用的值范围。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行:
$ python prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v {0,1,2}, --verbosity {0,1,2}
increase output verbosity
注意一下,我们的修改同时影响出错信息和帮助信息。
接下来,我们学习一个新的花样,使用 action=“count”来计数某个指定可选参数的出现次数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行结果
$ python prog.py 4
16
$ python prog.py 4 -v
4^2 == 16
$ python prog.py 4 -vv
the square of 4 equals 16
$ python prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python prog.py 4 -h
usage: prog.py [-h] [-v] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v, --verbosity increase output verbosity
$ python prog.py 4 -vvv
16
- 比起上个版本这个参数更加像一个flag (类似
action="store_true"
); - 该方法的实现效果有点类似“store_true” action;
- 和“store_true” action一样如果你没有指定
-v
flag,这个参数将被赋予None
; - 使用参数的长选项模式,可以得到一样的结果;
- 帮助信息并不能自动的更新这种新的用法, 我们可以修改代码来完善帮助信息(使用
help关键字
). - 最后一种调用方式图片那个样暴露了程序没有对超过预定次数重复制定该参数的处理方式的bug。
修复:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
# bugfix: replace == with >=
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行:
$ python prog.py 4 -vvv
the square of 4 equals 16
$ python prog.py 4 -vvvv
the square of 4 equals 16
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 11, in <module>
if args.verbosity >= 2:
TypeError: unorderable types: NoneType() >= int()
- 修复的方式是当value >= 2 选用同样的输出;
- 新的bug,没有对不指定该flag的处理方式
修复:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
使用一个新的关键字default
。将其设置为0,
使其可以和其他整型值作比较。请记住,在阐述没有指定值的时候,他将被默认赋值为None
, 这将导致没法和整型值作比较操作(将会产生TypeError
exception).
现在再看一下:
$ python prog.py 4
16
到这里,你已经可用argparse做很多事呢。除了这些基础的只是,本文还将继续讨论一些argparse深层次的用法。
再次深入
再次扩展我们的程序,添加一些其他的功能:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
elif args.verbosity >= 1:
print "{}^{} == {}".format(args.x, args.y, answer)
else:
print answer
执行:
$ python prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
$ python prog.py -h
usage: prog.py [-h] [-v] x y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbosity
$ python prog.py 4 2 -v
4^2 == 16
注意,到现在我怕们都是使用verbosity的等级来改变输出文本的格式。接下来将会使用不同的verbosity等级来改变输出的内容:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "Running '{}'".format(__file__)
if args.verbosity >= 1:
print "{}^{} ==".format(args.x, args.y),
print answer
执行以下:
$ python prog.py 4 2
16
$ python prog.py 4 2 -v
4^2 == 16
$ python prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16
冲突选项
以上我们已经讨论了argparse.ArgumentParser
其中的2个方法。接下来学习第三个方法add_mutually_exclusive_group()
。I这个方法用来让用户指定各个选项之间的冲突关系.。现在修改代码让大家更直观地认识到这个方法的作用。
引入--quiet
选项,这个选项与--verbose
互斥:
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
执行:
$ python prog.py 4 2
4^2 == 16
$ python prog.py 4 2 -q
16
$ python prog.py 4 2 -v
4 to the power 2 equals 16
$ python prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
注意几种不同的调用方式,无论是分别同时指定短选项还是混合长选项和短选项,程序都可以正常工作.
在初始化ArgumentParser类实例时,加入description参数可以在程序中添加信息告知用户关于该程序的主要信息。
示例:
import argparse
parser = argparse.ArgumentParser(description="calculate X to the power of Y")
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
注意usage信息。用法中指出了 [-v | -q]
,这就是说明用户可以指定-v
或者-q
,但是却不能同时指定:
$ python prog.py --help
usage: prog.py [-h] [-v | -q] x y
calculate X to the power of Y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbose
-q, --quiet
总结
argparse
提供了远比上文丰富的特性。本文仅仅是一个基础使用的教程。
Note
还有两个类似功能的模块, 分别是getopt
(类似C语言中的getopt()
) 和optparse
。其实argparse
是基于optparse
, 所以这两个模块的用法很相似。
概念
我们首先用LS命令做一个实例,来看一下本中即将介绍的一系列功能:
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
$ ls pypy
ctypes_configure demo dotviewer include lib_pypy lib-python ...
$ ls -l
total 20
drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
drwxr-xr-x 4 wena wena 4096 Feb 8 12:04 devguide
-rwxr-xr-x 1 wena wena 535 Feb 19 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Feb 7 00:59 pypy
-rw-r--r-- 1 wena wena 741 Feb 18 01:01 rm-unused-function.patch
$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...
以上四个命令中我们可以了解一些概念:
- ls没有任何参数时,ls命令依然可以发挥作用。 I默认显示该目录中所有上下文。
- 如果想让ls干一些超出默认功能的活,那么必须给ls更新的信息。比如我想让他显示一个其他目录
pypy
。只需要指定一个位置参数(position argument)。之所以叫位置参数是纯粹根据他在命令行中出现的位置,程序即可知道怎么处理这个参数。在一些其他的命令中这话中阐述具有更加重大的意义,比如cp, 它的基本用法即为:cp SRC DEST
。第一个参数表示你想拷贝的,第二个位置参数指定你需要拷贝到哪里去。 - 我们让系统显示每个文件的更多信息,而不是仅仅列出文件名。
-l
参数被称为一个可选参数(optional argument)。 - 这是帮助信息的片段节选.。当你偶然遇到一个以前从未用过的程序时这非常有用, 通过阅读帮助即可简单了解这个程序如何工作。
基础用法
首先来一个基本不做任何事情的实例:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
执行结果:
$ python prog.py
$ python prog.py --help
usage: prog.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
$ python prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo
Here is what is happening:
- 不带任何参数执行这个脚本时,标准输出没有任何内容。
第二个命令即可发现argparse
的一些用处。即什么都不用做,即可让你获得一个漂亮的帮助界面--help
选项, 也可用用段选项-h
, 是唯一一个不需要做任何代码即可实现的功能。指定任何其他的参数执行该脚本都会报错。
位置参数(Positional arguments)
例子:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo
执行结果:
$ python prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
$ python prog.py --help
usage: prog.py [-h] echo
positional arguments:
echo
optional arguments:
-h, --help show this help message and exit
$ python prog.py foo
foo
解释一下:
add_argument()
指定该命令行将会接受的参数。 这里指定了一个参数名为echo
。- 执行该程序将会需要指定一个参数。
parse_args()
方法会精确返回参数的值, 此例中即返回echo。
- 这是一个
argparse
内建支持的‘magic’类型变量(i.e. 无需指定变量来存储参数值)。你应该注意到 参数的名字 matches the string argument given to the method,echo
.
修改help信息使其更有用:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print args.echo
执行结果:
$ python prog.py -h
usage: prog.py [-h] echo
positional arguments:
echo echo the string you use here
optional arguments:
-h, --help show this help message and exit
尝试一些更有用的操作:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
print args.square**2
执行结果出错了!
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 5, in <module>
print args.square**2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
argparse
将会默认将参数传来的值作为strings处理, 除非我们指定它作为其他类型。接下来使用 argparse
将参数值作为int类型处理:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number",
type=int)
args = parser.parse_args()
print args.square**2
执行结果:
$ python prog.py 4
16
$ python prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'
OK!
可选参数(Optional arguments)
接下来看看如何添加一个可选参数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
print "verbosity turned on"
执行结果:
$ python prog.py --verbosity 1
verbosity turned on
$ python prog.py
$ python prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
optional arguments:
-h, --help show this help message and exit
--verbosity VERBOSITY
increase output verbosity
$ python prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument
解释一下:
- 这么编写程序是为了让他在指定
--verbosity
参数显示一些信息,没有指定时则不显示。 - 即使没加这个参数也可以执行这个程序并没有任何报错,可以确定这确实一个可选参数。默认情况下,当一个可选参数没有被使用时, 他的相关变量
args.verbosity
,将会使用None
作为值,从代码中if
语句判断的结果我们可以得出该结论。 - 注意帮助信息的变化。
- 使用
--verbosity
选项时, 你必须指定一个任意值。
上面例子中参数--verbosity
接受任意值,但是实际中我们只接受两个可用的参数值,比如True
or False。
可以如下修改代码:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
执行结果:
$ python prog.py --verbose
verbosity turned on
$ python prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1
$ python prog.py --help
usage: prog.py [-h] [--verbose]
optional arguments:
-h, --help show this help message and exit
--verbose increase output verbosity
- 这个选项相对于参数来说更像一个flag。 应该是用一个更贴近这种性质的参数名,比如
action,并
将其设置为"store_true"。
这么做的后果是:当你写带该参数,那么将会将args.verbose赋值为
. 反之则赋值为True
False
. - 注意帮助信息的变化。
短选项(short options)
例子:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
执行结果:
$ python prog.py -v
verbosity turned on
$ python prog.py --help
usage: prog.py [-h] [-v]
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
以上实现了同时指定 长选项名和短选项名。
结合位置参数和可选参数
我们的示例程序的复杂度进一步提升了:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print "the square of {} equals {}".format(args.square, answer)
else:
print answer
来看一看执行结果:
$ python prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
$ python prog.py 4
16
$ python prog.py 4 --verbose
the square of 4 equals 16
$ python prog.py --verbose 4
the square of 4 equals 16
- 以上程序指定了一个位置参数,一个可选参数。
- 执行命令时参数的顺序不影响。
下来我们赋予程序拥有多种详细值得能力:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行一下:
$ python prog.py 4
16
$ python prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
$ python prog.py 4 -v 1
4^2 == 16
$ python prog.py 4 -v 2
the square of 4 equals 16
$ python prog.py 4 -v 3
16
注意下当-v的值为3的时候, 这是程序的一个bug。如何让改善呢?现在我们通过add_argument()方法的choices入参来限制参数可用的值范围。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行:
$ python prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v {0,1,2}, --verbosity {0,1,2}
increase output verbosity
注意一下,我们的修改同时影响出错信息和帮助信息。
接下来,我们学习一个新的花样,使用 action=“count”来计数某个指定可选参数的出现次数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行结果
$ python prog.py 4
16
$ python prog.py 4 -v
4^2 == 16
$ python prog.py 4 -vv
the square of 4 equals 16
$ python prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python prog.py 4 -h
usage: prog.py [-h] [-v] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v, --verbosity increase output verbosity
$ python prog.py 4 -vvv
16
- 比起上个版本这个参数更加像一个flag (类似
action="store_true"
); - 该方法的实现效果有点类似“store_true” action;
- 和“store_true” action一样如果你没有指定
-v
flag,这个参数将被赋予None
; - 使用参数的长选项模式,可以得到一样的结果;
- 帮助信息并不能自动的更新这种新的用法, 我们可以修改代码来完善帮助信息(使用
help关键字
). - 最后一种调用方式图片那个样暴露了程序没有对超过预定次数重复制定该参数的处理方式的bug。
修复:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
# bugfix: replace == with >=
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
执行:
$ python prog.py 4 -vvv
the square of 4 equals 16
$ python prog.py 4 -vvvv
the square of 4 equals 16
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 11, in <module>
if args.verbosity >= 2:
TypeError: unorderable types: NoneType() >= int()
- 修复的方式是当value >= 2 选用同样的输出;
- 新的bug,没有对不指定该flag的处理方式
修复:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
使用一个新的关键字default
。将其设置为0,
使其可以和其他整型值作比较。请记住,在阐述没有指定值的时候,他将被默认赋值为None
, 这将导致没法和整型值作比较操作(将会产生TypeError
exception).
现在再看一下:
$ python prog.py 4
16
到这里,你已经可用argparse做很多事呢。除了这些基础的只是,本文还将继续讨论一些argparse深层次的用法。
再次深入
再次扩展我们的程序,添加一些其他的功能:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
elif args.verbosity >= 1:
print "{}^{} == {}".format(args.x, args.y, answer)
else:
print answer
执行:
$ python prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
$ python prog.py -h
usage: prog.py [-h] [-v] x y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbosity
$ python prog.py 4 2 -v
4^2 == 16
注意,到现在我怕们都是使用verbosity的等级来改变输出文本的格式。接下来将会使用不同的verbosity等级来改变输出的内容:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "Running '{}'".format(__file__)
if args.verbosity >= 1:
print "{}^{} ==".format(args.x, args.y),
print answer
执行以下:
$ python prog.py 4 2
16
$ python prog.py 4 2 -v
4^2 == 16
$ python prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16
冲突选项
以上我们已经讨论了argparse.ArgumentParser
其中的2个方法。接下来学习第三个方法add_mutually_exclusive_group()
。I这个方法用来让用户指定各个选项之间的冲突关系.。现在修改代码让大家更直观地认识到这个方法的作用。
引入--quiet
选项,这个选项与--verbose
互斥:
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
执行:
$ python prog.py 4 2
4^2 == 16
$ python prog.py 4 2 -q
16
$ python prog.py 4 2 -v
4 to the power 2 equals 16
$ python prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
注意几种不同的调用方式,无论是分别同时指定短选项还是混合长选项和短选项,程序都可以正常工作.
在初始化ArgumentParser类实例时,加入description参数可以在程序中添加信息告知用户关于该程序的主要信息。
示例:
import argparse
parser = argparse.ArgumentParser(description="calculate X to the power of Y")
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
注意usage信息。用法中指出了 [-v | -q]
,这就是说明用户可以指定-v
或者-q
,但是却不能同时指定:
$ python prog.py --help
usage: prog.py [-h] [-v | -q] x y
calculate X to the power of Y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbose
-q, --quiet
总结
argparse
提供了远比上文丰富的特性。本文仅仅是一个基础使用的教程。