天天看点

Python 命令行解析工具 Argparse介绍(二)

今天学习python的argparse模块。看到了这样一篇文章,链接 http://www.cnblogs.com/jianboqi/archive/2013/01/10/2854726.html,题目是Python 命令行解析工具 Argparse介绍(一),翻译自python官网上的一篇 toturial,很基础,看完了找介绍(二),却在原作者那里没找到,于是就自己接着前辈的文章继续把这个totural翻译完了。

选项参数

现在让我们来看一下如何添加选项参数,例子如下。

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

结果分析:

1 这个程序在给出—verbosity选项值为1的时候输出 verbosity turned on,在没有verbosity选项的时候什么都没有输出。

2 再次提醒这是一个可选的选项,可以看到当你在没有提供这个选项的情况下运行,程序不会报错(这点和“介绍一”中必选不同)

3 可以看到帮助信息中有些不同,optional arguments:

4 如果你使用这个选项的话,则必须要给出具体值,例子中是 1 ,你可以给定任何值。

在以上的例子中,导致程序输出不同只有一个因素,就是args.verbosity的值是ture还是false。我们可以进行一点更改

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity",
                    action="store_true")
args = parser.parse_args()
print type(args.verbose)#博主在这个地方加了一句输出type的代码,是因为由于上个例子里面给定的参数是1,很容易误解成布尔型变量,而实际上这个args.verbose是字符串,这也是为什么你输入任何参数值都会执行print "verbosity turned on”
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

结果分析:

1 在目前这种情况下(参数只有true和false两个值起作用),参数与其说是输入一个值,到时更像做一个标记(flag)。你也许已经注意到了,在上面的程序中,我们增加了一个新的关键字,action,并且赋值store.verbose,它表明,当使用选项的时候,就表示true,不使用则为false,当然在选项后面也无需添加参数,否则将会报错。

2 注意help和刚刚有所不同,verbose后面没有参数。

参数缩写

如果你对命令行比较熟悉的话,对于参数的缩写形式肯定不会陌生。下面我们将为verbose添加缩写v。非常的简单。

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

注意help的输出,你只需要在其中同时添加 -v 就可以了。

位置参数和选项参数结合

现在我们将我们的程序变得复杂一些。

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设置了输入为int型,然后分别输入参数,代表选择以不同的形式输出2的n次方。结果输出中却发现,除了1,2以外,所有其他参数值都是直接输出16(汗,你就这么写的怨谁)。所以,现在想把这个参数固定在0,1,2,就可以使用choice关键字,使用方法如下。

parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="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", "--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()

结果分析:

1 这个action非常好玩,赋值为count的时候变成了查这个v的个数来传递给args.verbosity。

2 注意一下这个错误,TypeError,当程序要求你输入一个必须参数,而你没有输入时,python会默认将这个参数赋值为None,None和int自然是不能比较的,于是引发了这个类型不匹配的错误。

最后,让我们来解决无参数时候程序崩溃的bug。根据你的编程经验,就该知道,default关键字出场了。给程序加入default关键字。

parser.add_argument("-v", "--verbosity", action="count", default=0,

                    help="increase output verbosity”)

输出:

$ python prog.py 4

16

冲突选项

下面介绍一下冲突选项的用法。使用方法add_mutually_exclusive_group()。

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)
           

输出

$ 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

可以从help中看到,这两个选项是互斥的。

结束语

argparse模块的功能自然远远要比这个强大,这个教程仅仅是一个基础篇,能够让大家快速入手。具体的大量事例用法请查看https://docs.python.org/2/library/argparse.html#module-argparse