Python腳本獲取命令行參數(shù)getopt、gnu_getopt

問(wèn)題

python腳本如何獲取命令行參數(shù)锨咙,包括選項(xiàng)及非選項(xiàng)參數(shù),例如:

python client.py -b -t timeout host port
python client.py -h
python client.py --help

相關(guān)模塊

python提供了sys模塊獲取參數(shù)侨赡,getopt模塊對(duì)參數(shù)進(jìn)行解析蓖租。

  • sys.argv:命令行參數(shù)粱侣,包含腳本名稱本身
  • sys.argv[0]:腳本名稱本身羊壹,如client.py
  • sys.argv[1:]:命令行參數(shù),不包括腳本名稱
  • getopt.getopt():解析命令行參數(shù)
  • getopt.gnu_getopt():解析命令行參數(shù)齐婴,選項(xiàng)和非選項(xiàng)可以混合在一起
  • getopt.GetoptError:解析命令行參數(shù)時(shí)的異常名稱
  • getopt.error:getopt.GetoptError的別稱油猫,向下兼容用

函數(shù)原型及說(shuō)明

getopt和gnu_getopt的原型如下:
getopt(args,options[,long_options])
gnu_getopt(args,options[,long_options])

  • args是參數(shù)列表,通常使用sys.argv[1:]柠偶,當(dāng)然也可以自己構(gòu)造一個(gè)參數(shù)列表情妖,如myargv=['-t', '60', '127.0.0.1', '8080']
  • options是短參數(shù),如-h诱担,-v毡证,-p 80。
  • long_options是長(zhǎng)參數(shù)蔫仙,如--help

函數(shù)調(diào)用說(shuō)明

舉例說(shuō)明料睛,對(duì)于如下調(diào)用:

try:
    opts, args = getopt.gnu_getopt(sys.argv[1:], "bht:", ['help','timeout='])
except getopt.GetoptError as e:
    print e
    sys.exit()
  1. "bht:": 當(dāng)一個(gè)選項(xiàng)只是表示開關(guān)狀態(tài)(不帶附加參數(shù))時(shí),分析串中只寫選項(xiàng)字符。當(dāng)選項(xiàng)帶附加參數(shù)時(shí)恤煞,分析串中寫入選項(xiàng)字符同時(shí)后面加一個(gè)":"號(hào)屎勘。所以"bht:"就表示"b"和"h"是開關(guān)選項(xiàng);"t:"則表示后面帶一個(gè)參數(shù)居扒。

  2. 調(diào)用getopt或gnu_getopt函數(shù)時(shí)概漱,函數(shù)返回兩個(gè)列表:opts和args。opts為分析出的格式信息喜喂。args為不屬于格式信息的剩余的命令行參數(shù)瓤摧。opts是一個(gè)兩元組的列表。每個(gè)元素為:(選項(xiàng)串,附加參數(shù))玉吁。如果沒(méi)有附加參數(shù)則為空串''姻灶。

  3. 使用長(zhǎng)格式分析串列表:['help','timeout=']。長(zhǎng)格式串也可以有開關(guān)狀態(tài)诈茧,即后面不跟"="號(hào)产喉。如果跟一個(gè)等號(hào)則表示后面還有一個(gè)參數(shù)。這個(gè)例子中敢会,"help"是一個(gè)開關(guān)選項(xiàng)曾沈;"timeout="則表示后面帶一個(gè)參數(shù)。

  4. 整個(gè)過(guò)程使用異常來(lái)包含鸥昏,這樣當(dāng)分析出錯(cuò)時(shí)塞俱,就可以打印出用法信息來(lái)通知用戶如何使用這個(gè)程序。

  5. 執(zhí)行程序時(shí)吏垮,對(duì)于短格式障涯,"-"號(hào)后面要緊跟一個(gè)選項(xiàng)字母。如果還有此選項(xiàng)的附加參數(shù)膳汪,可以用空格分開唯蝶,也可以不分開。長(zhǎng)度任意遗嗽,也可以用引號(hào)粘我。以下是正確的:
    -o
    -oa
    -obbbb
    -o bbbb
    -o'ccc'
    -o "a b"

  6. 執(zhí)行程序時(shí),對(duì)于長(zhǎng)格式痹换,"--"號(hào)后面要跟一個(gè)單詞征字。如果選項(xiàng)有附加參數(shù),后面要緊跟"="娇豫,再加上參數(shù)匙姜,"="號(hào)前后不能有空格,或者使用空格分隔選項(xiàng)和附加參數(shù)冯痢,以下是正確的:
    --timeout=30
    --timeout 30
    而這些是不正確的:
    -- timeout=30
    --timeout =30
    --timeout = 30
    --timeout= 30
    --timeout30

  7. getopt和gnu_getopt的區(qū)別在于氮昧,getopt是在非選項(xiàng)參數(shù)之后或详,所有的參數(shù)都被定義為非選項(xiàng)。而gnu_getopt則可以混用郭计,如:client.py -t 30 127.0.0.1 8080 -b霸琴。gnu_getopt是從python 2.3開始引入的。

  8. 長(zhǎng)選項(xiàng)會(huì)盡可能長(zhǎng)的識(shí)別昭伸,例如long_options為['foo','frob']梧乘,則--fo會(huì)匹配--foo。但是--f不會(huì)匹配庐杨,而拋出GetoptError異常选调。

實(shí)例

#!/usr/bin/env python
import sys, getopt

timeout = -1
TS = 0
bandwidth = 0

def usage():
    print("Usage: %s [OPTION]... [hostname] [port]" % (sys.argv[0]))
    print("  -b                  display bandwidth in bytes")
    print("  -h, --help          print this help and exit")
    print("  -t, --timeout time  connection timeout") 
    print("      --timestamp     display timestamp") 
    print("  -v, --version       print version information and exit") 

print("sys.argv=|%s|" % sys.argv)
try:
    opts, args = getopt.gnu_getopt(sys.argv[1:], "bht:v", ['help','timeout=','version',"timestamp"])
    print("opts=|%s|" % opts)
    print("args=|%s|" % args)
except getopt.GetoptError as e:
    print e
    usage()
    sys.exit()

for op, value in opts:
    if op == "-b":
        bandwidth = 1
    if op == "-h" or op == "--help":
        usage()
        sys.exit()
    if op in ("-t","--timeout"):
        timeout = value
    if op == "--timestamp":
        TS = 1
    if op in ("-v","--version"):
        print("%s version: 0.0.1" % sys.argv[0])
        sys.exit()

if len(args) != 2:
    print("no host or port")
    usage()
    sys.exit()

host=args[0]
try:
    port = int(args[1])
except ValueError as e:
    print e
    usage()
    sys.exit()

print("timeout=%s, host=%s, port=%d, bandwidth=%d, TS=%d" % (timeout, host, port, bandwidth, TS))

驗(yàn)證結(jié)果1

常用的調(diào)用方式

# python client.py -t 30 -b 127.0.0.1 8080
sys.argv=|['client.py', '-t', '30', '-b', '127.0.0.1', '8080']|
opts=|[('-t', '30'), ('-b', '')]|
args=|['127.0.0.1', '8080']|
timeout=30, host=127.0.0.1, port=8080, bandwidth=1, TS=0

驗(yàn)證結(jié)果2

選項(xiàng)和非選項(xiàng)混合的場(chǎng)景

# python client.py -t 30 127.0.0.1 8080 -b
sys.argv=|['client.py', '-t', '30', '127.0.0.1', '8080', '-b']|
opts=|[('-t', '30'), ('-b', '')]|
args=|['127.0.0.1', '8080']|
timeout=30, host=127.0.0.1, port=8080, bandwidth=1, TS=0

驗(yàn)證結(jié)果3

無(wú)附加參數(shù)的短選項(xiàng)合起來(lái)寫,“-b -t”可以寫為“-bt”

# python client.py -bt 30 127.0.0.1 8080
sys.argv=|['client.py', '-bt', '30', '127.0.0.1', '8080']|
opts=|[('-b', ''), ('-t', '30')]|
args=|['127.0.0.1', '8080']|
timeout=30, host=127.0.0.1, port=8080, bandwidth=1, TS=0
[root@test python]# 

驗(yàn)證結(jié)果4

短選項(xiàng)與附加參數(shù)合起來(lái)寫

# python client.py -bt30 127.0.0.1 8080
sys.argv=|['client.py', '-bt30', '127.0.0.1', '8080']|
opts=|[('-b', ''), ('-t', '30')]|
args=|['127.0.0.1', '8080']|
timeout=30, host=127.0.0.1, port=8080, bandwidth=1, TS=0

驗(yàn)證結(jié)果5

只有短選項(xiàng)灵份,且沒(méi)有附加參數(shù)

# python client.py -v
sys.argv=|['client.py', '-v']|
opts=|[('-v', '')]|
args=|[]|
client.py version: 0.0.1

驗(yàn)證結(jié)果6

只有長(zhǎng)選項(xiàng)仁堪,且沒(méi)有附加參數(shù)

# python client.py --version
sys.argv=|['client.py', '--version']|
opts=|[('--version', '')]|
args=|[]|
client.py version: 0.0.1

驗(yàn)證結(jié)果7

--ver匹配--version

# python client.py --ver
sys.argv=|['client.py', '--ver']|
opts=|[('--version', '')]|
args=|[]|
client.py version: 0.0.1

驗(yàn)證結(jié)果8

無(wú)法識(shí)別選項(xiàng)的異常

# python client.py -i
sys.argv=|['client.py', '-i']|
option -i not recognized
Usage: client.py [OPTION]... [hostname] [port]
  -b                  display bandwidth in bytes
  -h, --help          print this help and exit
  -t, --timeout time  connection timeout
      --timestamp     display timestamp
  -v, --version       print version information and exit

驗(yàn)證結(jié)果9

沒(méi)有必要的附加參數(shù)的異常

# python client.py -t
sys.argv=|['client.py', '-t']|
option -t requires argument
Usage: client.py [OPTION]... [hostname] [port]
  -b                  display bandwidth in bytes
  -h, --help          print this help and exit
  -t, --timeout time  connection timeout
      --timestamp     display timestamp
  -v, --version       print version information and exit

驗(yàn)證結(jié)果10

字符無(wú)法轉(zhuǎn)化成數(shù)字的異常

# python client.py 127.0.0.1 8080abc
sys.argv=|['client.py', '127.0.0.1', '8080abc']|
opts=|[]|
args=|['127.0.0.1', '8080abc']|
invalid literal for int() with base 10: '8080abc'
Usage: client.py [OPTION]... [hostname] [port]
  -b                  display bandwidth in bytes
  -h, --help          print this help and exit
  -t, --timeout time  connection timeout
      --timestamp     display timestamp
  -v, --version       print version information and exit

驗(yàn)證結(jié)果11

長(zhǎng)選項(xiàng)過(guò)短無(wú)法匹配的異常

# python client.py --time 127.0.0.1 8080
sys.argv=|['client.py', '--time', '127.0.0.1', '8080']|
option --time not a unique prefix
Usage: client.py [OPTION]... [hostname] [port]
  -b                  display bandwidth in bytes
  -h, --help          print this help and exit
  -t, --timeout time  connection timeout
      --timestamp     display timestamp
  -v, --version       print version information and exit
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市填渠,隨后出現(xiàn)的幾起案子弦聂,更是在濱河造成了極大的恐慌,老刑警劉巖氛什,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莺葫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡枪眉,警方通過(guò)查閱死者的電腦和手機(jī)捺檬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贸铜,“玉大人堡纬,你說(shuō)我怎么就攤上這事≥锴兀” “怎么了烤镐?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)渤早。 經(jīng)常有香客問(wèn)我职车,道長(zhǎng),這世上最難降的妖魔是什么鹊杖? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮扛芽,結(jié)果婚禮上骂蓖,老公的妹妹穿的比我還像新娘。我一直安慰自己川尖,他們只是感情好登下,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般被芳。 火紅的嫁衣襯著肌膚如雪缰贝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天畔濒,我揣著相機(jī)與錄音剩晴,去河邊找鬼。 笑死侵状,一個(gè)胖子當(dāng)著我的面吹牛赞弥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播趣兄,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼绽左,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了艇潭?” 一聲冷哼從身側(cè)響起拼窥,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹋凝,沒(méi)想到半個(gè)月后闯团,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仙粱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年房交,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伐割。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡候味,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隔心,到底是詐尸還是另有隱情白群,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布硬霍,位于F島的核電站帜慢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唯卖。R本人自食惡果不足惜粱玲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拜轨。 院中可真熱鬧抽减,春花似錦、人聲如沸橄碾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至史汗,卻和暖如春琼掠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背停撞。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工瓷蛙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怜森。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓速挑,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親副硅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姥宝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容