1. 程式人生 > >Python 命令列解析工具 Argparse介紹(二)

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