Argparse入門

argparse是 Python 標(biāo)準(zhǔn)庫中推薦的命令行解析模塊晨逝。它可以讓人輕松編寫用戶友好的命令行接口。對于深度學(xué)習(xí)等需要大量更換參數(shù)的工作懦铺,它可以將參數(shù)和代碼分開捉貌,讓工作更加簡潔。本文主要參考官方文檔冬念,并根據(jù)官方文檔重新進行了一些梳理趁窃。

1 創(chuàng)建一個 ArgumentParser對象

import argparse
parser = argparse.ArgumentParser()

2 位置參數(shù)

位置參數(shù):基于位置的參數(shù)。如定義一個函數(shù)def multiply(m,n), m和n就是位置參數(shù)急前。在argparse中醒陆,判斷位置參數(shù)的方法非常簡單,即不需要前綴以 - 或 -- 開頭的都是位置參數(shù)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print(args.echo)

我們將上述文件保存為prog.py裆针。 對于mac系統(tǒng)的話刨摩,假設(shè)我們將文件保存于桌面寺晌,打開終端,按照如下程序運行澡刹。若保存于別的位置可以將prog.py文件拖入終端折剃,可以直接顯示文件的絕對路徑。

$ cd /Users/xxx/Desktop
$ python3 prog.py --help
usage: prog.py [-h] echo

positional arguments:
  echo

optional arguments:
  -h, --help  show this help message and exit

通過help屬性我們發(fā)現(xiàn)像屋,位置參數(shù)為echo怕犁,可選參數(shù)為-h,--help己莺,實際上-h為--help的簡寫奏甫,這個后面會說到。

$ python3 prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo

這時我們發(fā)現(xiàn)程序報錯凌受。這是因為位置參數(shù)需要制定內(nèi)容阵子。我們不妨給echo隨意指定一個詞 'foo'

$ python3 prog.py foo
foo

接下來我們可以繼續(xù)豐富echo屬性的功能

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print(args.echo)
$ python3 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

相比之前,除了位置參數(shù)和可選參數(shù)胜蛉,我們還看到了對位置參數(shù)echo的描述挠进。

接下來我們定義一些更有實際意義的屬性

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)
$ python3 prog.py 4
Traceback (most recent call last):
  File "prog.py", line 13, in <module>
    print(args.square**2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

報錯,因為程序把輸入自動處理成了str誊册,而str是不能做數(shù)值運算了领突,我們告訴 argparse來把這一輸入視為整數(shù)

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)
$ python3 prog.py 4
16

3 可選參數(shù)

可選參數(shù):在argparse中,凡是用 - 或者 -- 開頭定義的命令行參數(shù)案怯。這里有一個約定俗成的慣例:單個字母只是用一個 - 君旦,多個字母使用兩個 - (--)。對于可選參數(shù)來說嘲碱,如果沒有被使用的話金砍,如就默認為None,下面我們來定義一個可選參數(shù)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
    print("verbosity turned on")

test1

$ python3 prog.py --verbosity 1
verbosity turned on

我們給verbosity指定1麦锯,if條件判斷為True

test2

$ python3 prog.py

我們沒有使用verbosity屬性恕稠,args.verbosity == None,if條件判斷為false

test3

$ python3 prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument

我們使用了verbosity屬性扶欣,但是沒有給其賦值鹅巍,報錯

上述例子接受任何整數(shù)值作為 --verbosity 的參數(shù),但對于我們的簡單程序而言宵蛀,只有兩個值有實際意義:True 或者 False昆著。讓我們據(jù)此修改代碼:

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")

現(xiàn)在指定了一個新的關(guān)鍵詞 action,并賦值為 "store_true"术陶。這意味著凑懂,當(dāng)這一選項存在時,為 args.verbose 賦值為 True梧宫。沒有指定時則隱含地賦值為 False

test1

$ python3 prog.py --verbose
verbosity turned on

test2

$ python3 prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1

給verbose指定了具體的值報錯

test3

$ python3 prog.py --help
usage: prog.py [-h] [--verbose]

optional arguments:
  -h, --help  show this help message and exit
  --verbose   increase output verbosity

4 短選項

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")

這里-v為--verbose的縮寫接谨,

$ python3 prog.py -v
verbosity turned on

我們通過-v也可以調(diào)用verbose屬性

$ python3 prog.py --help
usage: prog.py [-h] [-v]

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  increase output verbosity

5 結(jié)合位置參數(shù)和可選參數(shù)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number") #增加一個位置參數(shù)
parser.add_argument("-v", "--verbose", action="store_true",
                    help="increase output verbosity") #增加一個可選參數(shù)
args = parser.parse_args()
answer = args.square**2
if args.verbose:
    print("the square of {} equals {}".format(args.square, answer))
else:
    print(answer)

test1

$ python3 prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square 

沒有給位置參數(shù)square指定值

test2

$ python3 prog.py 4
16

沒有使用可選參數(shù)摆碉,位置參數(shù)傳入4

test3

$ python3 prog.py 4 --verbose
the square of 4 equals 16

使用了可選參數(shù)verbose,位置參數(shù)square為4

test4

$ python3 prog.py --verbose 4
the square of 4 equals 16

改變傳入?yún)?shù)的順序脓豪,結(jié)果不變
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

假設(shè)我們想限定verbose的輸入選擇

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") #這里我們限定verbose只接受三個input:0 , 1, 2
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)

test

$ python3 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)

給verbose傳入3程序報錯

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
我們引入了另一種動作 count巷帝,來數(shù)某一個可選參數(shù)出現(xiàn)了幾次

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") #這里action從store_ture變成了count
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)
$ python3 prog.py 4 #0次
16
$ python3 prog.py 4 -v #1次
4^2 == 16
$ python3 prog.py 4 -vv #2次
the square of 4 equals 16
$ python3 prog.py 4 --verbosity --verbosity #2次
the square of 4 equals 16
$ python3 prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python3 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
$ python3 prog.py 4 -vvv #三次
16

對于上述程序做進一步改進,我們想統(tǒng)計所有大于等于0的次數(shù)

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)
$ python3 prog.py 4 -vvv
the square of 4 equals 16
$ python3 prog.py 4 -vvvv
the square of 4 equals 16
$ python3 prog.py 4
Traceback (most recent call last):
  File "prog.py", line 11, in <module>
    if args.verbosity >= 2:
TypeError: '>=' not supported between instances of 'NoneType' and 'int'

我們看到最后一次報錯扫夜,這是因為不使用verbosity屬性的話默認值是None楞泼,而None是不能進行數(shù)值比較的,所以不妨令不使用verbosity的默認值為0

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)

再次測試

$ python3 prog.py 4
16

Reference:
[https://docs.python.org/zh-cn/3/library/argparse.html]
[https://docs.python.org/zh-cn/3/howto/argparse.html]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笤闯,一起剝皮案震驚了整個濱河市堕阔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颗味,老刑警劉巖超陆,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浦马,居然都是意外死亡时呀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門晶默,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谨娜,“玉大人,你說我怎么就攤上這事荤胁∏圃ぃ” “怎么了屎债?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵仅政,是天一觀的道長。 經(jīng)常有香客問我盆驹,道長圆丹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任躯喇,我火速辦了婚禮辫封,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘廉丽。我一直安慰自己倦微,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布正压。 她就那樣靜靜地躺著欣福,像睡著了一般。 火紅的嫁衣襯著肌膚如雪焦履。 梳的紋絲不亂的頭發(fā)上拓劝,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天雏逾,我揣著相機與錄音,去河邊找鬼郑临。 笑死栖博,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的厢洞。 我是一名探鬼主播仇让,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼躺翻!你這毒婦竟也來了妹孙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤获枝,失蹤者是張志新(化名)和其女友劉穎蠢正,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體省店,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡嚣崭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了懦傍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雹舀。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖粗俱,靈堂內(nèi)的尸體忽然破棺而出说榆,到底是詐尸還是另有隱情,我是刑警寧澤寸认,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布签财,位于F島的核電站,受9級特大地震影響偏塞,放射性物質(zhì)發(fā)生泄漏唱蒸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一灸叼、第九天 我趴在偏房一處隱蔽的房頂上張望神汹。 院中可真熱鬧,春花似錦古今、人聲如沸屁魏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氓拼。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間披诗,已是汗流浹背撬即。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呈队,地道東北人剥槐。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像宪摧,于是被迫代替她去往敵國和親粒竖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353