python接受命令行參數:About argparse module

 

這是一篇argparse入門級教程,如果您已對argparse有部分了解,這篇博文不適合您,無需在這裏浪費時間。

 

##速查目錄

1.創建對象argparse.ArgumentParser() 有一個description參數對程序進行介紹

2.增加參數parser.add_argument()

3.解析參數parser.parse_args()

4.添加衝突組parser.add_mutually_exclusive_group()

 

##add_parse_args參數說明

1.-參數縮寫,--參數全稱

2.help 參數說明(string)

3.action (string)可以當一個flag使用

    為store_true時會對參數進行bool賦值

    為count時,會根據參數個數為其進行int賦值 如-v就是1,-vv就是2等。不指定會None

4.default,在不指定參數時會被賦值,可以和count聯合起來使用

5.type 指定接受的參數類型(該是什麼類型就是什麼類型)

6.choices (list)指定optional argument可選範圍
 

之所以把它寫在前面就是爲了讓它能起到速查的效果。筆記用的是繁體,我就不修改了,聯繫前後文差不多也能看懂(也當做鍛鍊你識別繁體能力的手段)。

 

進入正題。很多時候,我們需要提供一個很好的命令行接口,簡化程序交互的同時,也要方便用戶的使用。說的大白話一點,就是程序如何簡單優雅地處理命令行參數。

 

我猜你第一想到的就是sys.argv,雖然不經常使用,但是很清楚它能夠解決問題。

 

編輯腳本代碼wowotou.py(這個文件的名字後面說明):

import sys

print(sys.argv)

 

在當前目錄下打開命令行嵌入:python wowotou.py -h hello world

                             

程序返回一個list,而其中的items是命令中“python”之後的所有被分隔開的“參數”。“wowotou.py”是第一個,“-h”是第二個以此類推。

 

當我們在程序中需要使用這些參數的時候,就可以通過列表取下標的方法來調用參數。例如sys.argv[0],sys.argv[1]等等。

 

在簡單的程序處理中,這種應對方式完全可以勝任。當程序設計稍微一複雜時,這種方式就顯得不那麼的盡人意。

 

比如,程序需要接受一個x值,一個y值,加一個半徑r值。來求得一個圓的面積(我知道座標沒啥用,在舉例子嘛)。

 

程序中你可能會這樣寫:

answer = sys.argv[2] * 2 * math.PI

 

好像沒有什麼問題呀?的確,但是你認爲的正確是理所當然了。

 

這個程序的成功執行,是在用戶必須知道他輸入的第一個參數是x的值,第二個參數是y的值等等諸如此類增加記憶負擔的詞。簡單點說,就是你要求用戶記住你程序接受參數的順序,還不能出錯。

 

來看看argparse是怎麼優化的吧,學完後,你可能就會放棄sys.argv了。

 

argparse同樣也是標準庫,不需要再次下載。

 

我們將代碼清空:

                                    

一般情況下,python程序不會對文件之後的任何參數進行處理。當你導入argparse時:

import argparse

parser = argparse.ArgumentParser() //創建解析器對象

parser.parse_args() //解析命令行參數

print("嘿嘿")

(get到兩個基礎的方法)

 

                              

首先程序運行wowotou文件就無須多講了。當我們在其之後多加入一個-h參數的時,輸出了一些解釋信息,其中的optional arguments(可選參數)解釋了-h參數的含義“show this help message and exit”。如果我們將其換爲--help,會得到同樣的結果。

 

這裏的-h和--help有什麼區別呢?emmm,一個是縮寫,一個是全寫。這裏先做了解,我們會慢慢的深入解釋。

 

還有一點,在創建解析器對象的時候,可以添加一個參數description(value爲string類型),看單詞就能猜個八九不離十(你要是非猜一,那我也沒辦法),是對參數解釋器目標任務的說明。

 

稍加修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.parse_args()

print("嘿嘿")

 

                                     

這時再輸入相同的命令,就可以查看到你寫的信息了。這對用戶來說也是個不錯的提示方式吧。

 

目前爲止,在我們只是簡單的引入argparse,並對參數進行解析後。程序可以處理的一個可選參數是-h或--help,這是唯一一個不需要指定的可選參數。那如果指定我們的自定義參數呢?

 

就是速查中的2,使用add_argument()

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


print(args.food,",嘿嘿")

 

我們加入了一個指定參數,參數名稱爲food,對參數的調用可以直接通過解析後的對象使用“.”運算符+變量名來使用。

 

                              

命令行中python wowotou.py之後的第一個參數會被當做food的值(你可以把命令行裏的food修改爲任意的值)。在程序代碼中我們只是添加了一個名稱爲food的參數,程序會默認把第一個參數當做food的值。例如第二條命令中,除了給予了一個“food”的字符串外,還多給了一個“wowo”字符串。程序會將“food”賦值給food參數,而wowo並不知道怎麼處理,就會報錯。

 

如果這時使用-h查看幫助信息:

                                           

你會驚奇的發現,除了optional arguments參數列表外,多了一個positional arguments,其中只有一個參數,就是我們指定的參數food。

 

第一個點,關於positional arguments的翻譯。我習慣性的說成“位置參數”,有些編程書上翻譯爲“按位實參”。這個名稱更多的會出現在函數裏。比如function(value1, value2, key=value3)中,value1和value2都被稱爲positional argument,而key更習慣的稱爲關鍵詞實參。

 

第二個點,關於argument和parameter的理解。我們知道,兩個詞都有參數的意思,區別點在於一般argument指實參,parameter指形參。

 

說了這麼多,也只是爲了幫助你理解positional arguments這個詞的含義。選擇你喜歡的翻譯方式吧。

 

在argparse中,簡單說,位置參數就是必須指定(給予)的參數,即在命令行中必須提供的參數。

 

                    

如果沒給,模塊就會提示你需要一個值,爲名稱是food的參數賦值。

 

從這裏引入optional arguments,我們知道-h參數是屬於這個類別的,而且它和positional arguments的區別就是,這個參數可給可不給。就像我們直接執行python + 文件名,程序也可以正常運行。而不像food參數,不給就會報錯。

 

下個問題,那,我們如何制定自己的可選參數?

 

很簡單,參數名前加-或者--。(-和--的區別前面已經說明)

 

稍加修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(",嘿嘿")

這時再打開幫助信息:

                                       

自定義的可選參數就被加入到optional arguments的行列中。和-h參數的說明一對比,我們的-w顯得特別骨感。再修改:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w", "--wowotou", help="a food named wowotou")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(",嘿嘿")

                                     

對比着,我們也就知道了全稱是怎麼設計出來的,以及-h後面的"show this help message and exit"的信息是怎麼顯示出來的了。

 

到目前爲止,我們還沒能做出一點能看的東西。別急,先來看add_argument的第一個關鍵字參數action。

 

這篇文章中,action只有兩個value(string 類型),一個store_true,另一個是count。先來說store_true。

 

當action爲store_true時,會根據命令行中參數的有無來對參數進行bool賦值。

 

什麼意思呢?

 

比如:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

if args.wowotou:
    print("窩窩頭,一塊錢四個,嘿嘿")

我們對-w參數添加了store_true的action參數。當這個參數爲true時,print一條語句,否則什麼都不做。

 

(通過args解析對象調用參數,必須是那個全稱的名字,即必須是args.wowotou,而不能是args.w)

 

                                      

不給參數的時候,all is well。

 

給了-w參數,成功輸出,--wowotou同上。

 

通過這個例子,我們就曉得了store_true的功能了,當命令行中提供了這個可選參數,就會將其置爲true,否則置爲false。

 

嘿嘿,好像開始有趣了。繼續吧。

 

我現在不想賣窩窩頭了,我想賣大饅頭。我們再將food參數加回來:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窩窩頭,一塊錢四個,嘿嘿")

print(args.food,"一塊錢四個,嘿嘿")

我們知道,positional arguments是必須給的,而參數的值,就是你命令行中的值。如上:

                                 

給food參數的賦值是大饅頭。

 

到此,我們通過位置參數得到售賣的商品,而用可選參數執行某些操作。

 

當職位提升後,我就可以制定價格了,比如一塊錢一個,一塊錢兩個等等。

 

很簡單,再添加一個位置參數接收個數。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窩窩頭,一塊錢四個,嘿嘿")

print(args.food,"一塊錢",args.num,"個,嘿嘿")

                                        

水面風平浪靜,一般海底都波濤洶湧。

 

經理知道你擅自修改數據後,很生氣,在程序裏面對你的值進行了修改。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窩窩頭,一塊錢四個,嘿嘿")

print(args.food,"一塊錢",args.num - 1 ,"個,嘿嘿")

最後在print的時候,將你的args.num減了一個。好像沒什麼問題吼~

 

                        

再次執行出錯了,原因是程序通過命令行接受的參數類型只有一種類型,就是string。

 

兩種方法解決,得到數據後,對數據進行類型轉換。弊端,接收到的string(用戶輸入的,具有主觀性)並不一定能轉換成你想要的類型。(比如將“hahaha”轉換成int類型)

 

這時,可以使用一個參數type來指定你想要接受的類型:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("num", type=int, help="how many can I buy for one dollar")

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窩窩頭,一塊錢四個,嘿嘿")

print(args.food,"一塊錢",args.num - 1 ,"個,嘿嘿")

我們在num參數中加入了type參數,來告訴程序,我要的num參數的值是個int類型。這時:

                                         

完美執行了。那如果用戶給的不是int類型呢?

                            

會告訴你,這是個無效的int值。如此,用戶就知道了,我這裏需要給個整數。

 

在你得知經理不滿後,主動認錯。經理也退讓了一步,同意你指定價格,不過要在他規定的範圍內。引入下一個參數choices,這個參數的類型是list。

 

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("food", help="a name of food")

parser.add_argument("-n", "--num", type=int, help="how many can I buy for one dollar", choices=[1,2,3,4])

##parser.add_argument("-w", "--wowotou", help="a food named wowotou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量


##if args.wowotou:
##    print("窩窩頭,一塊錢四個,嘿嘿")

print(args.food,"一塊錢",args.num,"個,嘿嘿")

我們將num改爲可選參數,並加入了choices。現在num參數的給定值,就只能在choices範圍裏面挑了:

  

而當你超出範圍時,就會警告你,並告訴你範圍集。

 

繼續繼續。

 

我們再將程序修改一下,介紹下一個參數,default:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-f","--food", help="the name of food", default="窩窩頭")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(args.food,"一塊錢四個,嘿嘿")

將food參數修改爲optional argument,並加入default參數賦值string類型“窩窩頭”。

 

在不指定-f參數的情況下,會默認賦值“窩窩頭”,在給定參數的情況下,會覆蓋掉默認參數。

 

如:

                                   

代碼中default被賦值了字符串類型的常量,你可以賦值任何你想要類型。甚至是一個函數(如max,min等等)。

 

致此,還有一個點沒有說到,就是action的count行爲。我是認爲,這個count可以作爲一種等級處理。

 

舉個例子,你擺小攤賣窩窩頭,有被沒收小推車的風險。我們創建一個參數w代表warning。並用count來表示warning的等級。

 

show code:

import argparse

parser = argparse.ArgumentParser("What are you selling?")

parser.add_argument("-w","--warning", action="count", default=0)

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

print(args.warning)

if args.warning == 0:
    print("淡定,沒事~")
elif args.warning == 1:
    print("我現在內心有點慌。。。")
elif args.warning == 2:
    print("時刻準備着---")
else:
    print("跑!")

count的行爲,會計算命令行中此參數的出現次數,無論是縮寫還是全稱。(爲了便於演示,在執行判斷之前,我們把參數值輸出一下。)

 

直接看使用吧:

                               

對比一下,很容易就能理解。

 

(這裏有一個點,需要說明,當action="count"和default=一個整數同時使用的時候。最終參數的值是default的值加上count的計數值。比如你的default=1,在命令行中參數出現次數爲1的時候,程序中這個參數的值就是2。如果default是3,那值爲4。)

 

還有一個函數:add_mutually_exclusive_group()

 

函數名直譯就是“添加相互獨立組”,這個是幹什麼用的呢?其實就是限制某些參數同時出現,舉個例子,你不能同時賣“窩頭”和“饅頭”。如果我們用w代表窩頭,m代表饅頭,那參數w和m不能同時出現。

 

這個函數就是幹這件事用的。

import argparse

parser = argparse.ArgumentParser("What are you selling?")

group = parser.add_mutually_exclusive_group()

##將w和m參數加入到同一個衝突組中
group.add_argument("-w","--wowotou", action="store_true")
group.add_argument("-m", "--mantou", action="store_true")

args = parser.parse_args() #為了方便調用,我們將他賦值給一個變量

if args.wowotou:
    print("窩窩頭,一塊錢四個,嘿嘿")
elif args.mantou:
    print("大饅頭,一塊錢四個,嘿嘿")

使用示例:

    

在參數w和m同時出現時,就會對你發出警告,m參數不允許和參數w一起出現。

 

全部的入門內容已經講述完畢了,剩下最後一個伏筆沒有解釋。那就是對文件名“wowotou”的含義說明,不過現在看來,已經沒那個了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章