1. 程式人生 > 程式設計 >python入門:argparse淺析 nargs='+'作用

python入門:argparse淺析 nargs='+'作用

我就廢話不多說了,大家還是直接看程式碼吧~

#aaa.py
#version 3.5
import os #這句是沒用了,不知道為什麼markdown在編輯程式碼時,不加這一句,就不能顯示程式碼高亮[汗]
import argparse

parser = argparse.ArgumentParser(description='Process some integers...') #初始化一個分析器
#parser.add_argument(中的引數)
#__init__(self,option_strings,dest,nargs=None,const=None,default=None,type=None,choices=None,required=False,help=None,metavar=None)
parser.add_argument('integers',metavar='N',type=int,nargs='+',help='an integer for the accumulator') 
   #這是一個新增【位置引數】
   #第一個引數是自定義的引數名,在程式碼中用來計算的(parser.parse_args().integers*2)
 
parser.add_argument('--sum',dest='accumulate',action='store_const',const=sum,default=max,help='sum the integers(default:find the max)')
   #這是一個新增【可選引數】
   #第一個引數是自定義的引數【在程式碼中的使用parser.parse_args().sum】【在系統命令列中的使用:>python aaa.py --sum
 
args = parser.parse_args()
print(args)  #Namespace(accumulate=<built-in function sum>,integers2=[1,2,3,4])
print(args.integers) #integers要與上面的對應
print(args.accumulate(args.integers)) #accumulate要與上面的對應
import argparse
def infer(args):
 for img in args.imgs:
 print("\n=== {} ===".format(img))
if __name__ == '__main__':
 parser = argparse.ArgumentParser()
 parser.add_argument('--imgs',type=str,nargs='+')
 args = parser.parse_args()
 infer(args)

結果

python入門:argparse淺析 nargs=&#39;+&#39;作用

補充知識:argparse解析命令列引數

argparse簡介:

在argparse中,最常用的就是上述三部分了:建立一個ArgumentParser物件;使用add_argument()方法來為建立的ArgumentParser物件新增argument的解析規則;最後呼叫parse_args()來解析傳入的內容,依據的是第二步制定的規則,生成的是一個Namespace物件,若未傳引數給parse_args(),那麼預設從sys.argv來獲取命令列入參。

建立一個ArgumentParser:

函式原型為:

ArgumentParser(prog=None,usage=None,description=None,epilog=None,parents=[],formatter_class=argparse.HelpFormatter,prefix_chars='-',fromfile_prefix_chars=None,argument_default=None,conflict_handler='error',add_help=True)

1、prog:程式的名字,預設是argv[0]。若設定,則在幫助資訊中,可以使用%(prog)s來作為格式化的引用(修改一處全域性受用)。

2、usage:幫助資訊的usage欄位,描述程式的各種用法,預設情況下會依據add_argument()來自動生成。

3、description:一個簡單描述程式主要幹啥以及怎麼用的字元段,預設為空。

4、epilog:optional arguments字元段之後的字元段,預設為空。

5、parents:繼承的父parser,為了避免一些公共的內容重複定義,父parser在初始化時會設定add_help=False,這是為了防止出現父與子parser的-h衝突而丟擲異常。

6、formatter_class:對於help輸出進行格式化,除了輸出的樣式外,如果設定為ArgumentDefaultsHelpFormatter,則會自動在help輸出中新增已定義的default值。

7、prefix_chars:options前的字元,預設為'-',可以新增其他字元,如'-+',但是如果沒有包括'-',那麼對應的option如'-h'就無法解析。

8、fromfile_prefix_chars:有時會使用檔案給parse_args()傳入引數,為了能夠識別檔案字串,如"demo.txt",需要設定此值,如"@",那麼所有以此字元為開頭的字串都被當作是檔案,所以傳給parse_args()的引數應該是@demo.txt。在該檔案中,一行只能有一個引數。如檔案中的'-f\nbar'會被解析成['-f','bar']。

9、argument_default:一般情況下,預設值使用add_argument()來新增,或者使用set_defaults()設定一些鍵值對來新增。剩下一種情況就是設定此項(此處沒看明白是咋回事)。

10、conflict_handler:解決在add_argument()階段有衝突的option的依據策略,預設為error即丟擲異常。一般情況下遇到衝突是丟擲異常即可,但是如果設定了parents,那麼需要重寫父parser中的規則的時候,就需要將此項設定為resolve,但是重寫是精確匹配的,如老規則定義了-h/--help,重寫了-h,那麼--help還是老規則。

11、add_help:是否新增-h/--helpoption,預設為True。為False時,是要做parent(其實可以設定子Parser重寫)。預設是-h/--help,若prefix_chars中沒有包含'-',那麼就以其中第一個字元作為代替。

呼叫add_argument()新增解析規則:

函式原型:

ArgumentParser.add_argument(name or flags...[,action][,nargs][,const][,default][,type][,choices][,required][,help][,metavar][,dest])

1、name or flags:是位置引數,則需要傳入名字;要是可選引數,則需要進行定義,如'-f','--foo'。

2、action:定義傳入的引數如何處理。

action='store',預設取值,儲存傳入引數。

action='store_const',需要新增const,意味著該argument的值不從命令列輸入,而是取const的值。

action='store_true' or action='store_false','store_const'的特殊情形,意味著const的值為True或False。

action='append',表示傳入的值會作為一個列表的一項,意味著option可以在命令列中多次出現。

action='append_const',傳入列表的項由const定義,通常用在需要多個argument將值傳入一個列表中的場景。

action='count',輸出argument出現的次數。

action='help',已預設新增。

action='version',需要定義version,使用時輸出版本資訊並退出。

自定義,通過定義一個argparse.Action子類來實現。實際上,上面的這些可選項都是通過這種形式定義的。

3、nargs:ArgumentParser物件通常將一個動作與一個命令列引數關聯。nargs關鍵字引數將一個動作與不同數目的命令列引數關聯在一起:

nargs=N,一個選項後可以跟多個引數(action='append'時,依然是一個選項後跟一個引數,只不過選項可以多次出現),引數的個數必須為N的值,這些引數會生成一個列表,當nargs=1時,會生成一個長度為1的列表。

nargs=?,如果沒有在命令列中出現對應的項,則給對應的項賦值為default。特殊的是,對於可選項,如果命令列中出現了此可選項,但是之後沒有跟隨賦值引數,則此時給此可選項並不是賦值default的值,而是賦值const的值。

nargs=*,和N類似,但是沒有規定列表長度。

nargs=+,和*類似,但是給對應的項當沒有傳入引數時,會報錯error: too few arguments。

nargs=argparse.REMAINDER,所有剩餘的引數,均轉化為一個列表賦值給此項,通常用此方法來將剩餘的引數傳入另一個parser進行解析。如果nargs沒有定義,則可傳入引數的數量由action決定,通常情況下為一個,並且不會生成長度為一的列表。

4、const,一種是定義action='store_const'或action='append_const'時使用。一種是定義nargs='?'時,可選項出現在命令列中,但之後並沒有跟隨賦值的引數,作為預設值傳給此可選項。

5、default:預設值。

如果是一個字串,那麼Parser解析的時候會將它作為命令列傳入值,使用type的值來進行轉換型別,但是如果不是的話,就會使用定義的值而不進行型別轉換。如果設定了nargs='?'或nargs='*',那麼當沒有引數賦值給該項時,會使用default定義的值。

而default=argparse.SUPPRESS時,則表示命令列中未出現某一項時,不會對它進行預設賦值。

6、type:用於型別檢查和型別轉換。

使用FileType可簡化對檔案的操作。還可以自定義函式,輸入是一個字串,輸出是轉換後的字串。當設定choices的時,型別檢查會變得容易,因為只需要在一個範圍內比較即可。

7、choices:給定了取值範圍,超出會報錯。

當type也有定義時,會先使用type進行型別檢查,所以choices中的取值必須符合type的定義,否則在parse_args()時會報錯。任何支援in操作符的均可作為choices的賦值,所以字典,列表,集合,等等其他容器均都支援。

8、required:預設情況下,可選項(前面有'-')被認為並不一定需要出現在命令列引數中,但是如果設定了required=True的話,則必須出現。此類設定違揹人的常識,應避免使用。

9、help:幫助資訊。

之前提到的%(prog)s可用於此處程式名的格式化,此外,還有%(default)s格式化default的值,%(type)s格式化type的值。

設定為argparse.SUPPRESS可不顯示幫助資訊。

10、metavar:在Parser生成幫助資訊時,需要有字元代表需要傳入的值。(這一段和dest相同,使用的就是dest的值)如果是位置引數,則用它本身代替;如果是可選引數,則使用它的大寫來代替。使用metavar可替換預設的字元。

11、dest:大部分的選項都需要通過命令列來給其賦值,這些值的名字通過dest來定義,預設的規則如同metavar中所述。

呼叫parse_args()解析

函式原型:

ArgumentParser.parse_args(args=None,namespace=None)

將args轉換為namespace物件的一個值。預設情況下,sys.argv賦值給args,一個空的Namespace物件會被建立。解析時,會對傳入的引數進行檢查,若不符合要求就會報錯。一般情況下,會自動判斷傳入的值到底是一個可選引數,還是一個負數(都用'-'開頭)。但有時位置引數的值必須是一個'-'開頭的值,如'-f',那麼使用parser.parse_args(['--','-f']),'--'代表後續的所有傳入值都需要看做是位置引數。parse_args()會返回填充好的Namespace物件

例項:

以faster rcnn程式碼中的命令列解析為例:

#coding=utf-8
import argparse
import sys
 
def parse_args():
 parser = argparse.ArgumentParser(description='Train a Fast R-CNN network')
 parser.add_argument('--cfg',dest='cfg_file',help='optional config file',type=str)
 parser.add_argument('--weight',dest='weight',help='initialize with pretrained model weights',type=str)
 parser.add_argument('--imdb',dest='imdb_name',help='dataset to train on',default='voc_2007_trainval',type=str)
 parser.add_argument('--imdbval',dest='imdbval_name',help='dataset to validate on',default='voc_2007_test',type=str)
 parser.add_argument('--iters',dest='max_iters',help='number of iterations to train',default=70000,type=int)
 parser.add_argument('--tag',dest='tag',help='tag of the model',type=str)
 parser.add_argument('--net',dest='net',help='vgg16,res50,res101,res152,mobile',default='res50',type=str)
 parser.add_argument('--set',dest='set_cfgs',help='set config keys',nargs=argparse.REMAINDER)
 
 if len(sys.argv) == 1:
 parser.print_help()
 sys.exit(1)
 args = parser.parse_args()
 return args
 
if __name__ == '__main__':
 args = parse_args()
 print(args)

將以上程式碼儲存為test.py,然後在命令列輸入:python test.py

結果為:

usage: test.py [-h] [--cfg CFG_FILE] [--weight WEIGHT] [--imdb IMDB_NAME]
  [--imdbval IMDBVAL_NAME] [--iters MAX_ITERS] [--tag TAG]
  [--net NET] [--set ...]

Train a Fast R-CNN network

optional arguments:
 -h,--help  show this help message and exit
 --cfg CFG_FILE optional config file
 --weight WEIGHT initialize with pretrained model weights
 --imdb IMDB_NAME dataset to train on
 --imdbval IMDBVAL_NAME
   dataset to validate on
 --iters MAX_ITERS number of iterations to train
 --tag TAG  tag of the model
 --net NET  vgg16,mobile
 --set ...  set config keys

在命令列輸入:

python test.py --weight data/imagenet_weights/vgg16.ckpt \
 --imdb voc_2007_trainval \
 --imdbval voc_2007_test \
 --iters 7000 \
 --cfg experiments/cfgs/vgg16.yml \
 --net vgg16  \
 --set ANCHOR_SCALES "[8,16,32]" ANCHOR_RATIOS "[0.5,1,2]" TRAIN.STEPSIZE "[50000]"

結果為:

Namespace(cfg_file='experiments/cfgs/vgg16.yml',imdb_name='voc_2007_trainval',imdbval_name='voc_2007_test',max_iters=7000,net='vgg16',set_cfgs=['ANCHOR_SCALES','[8,32]','ANCHOR_RATIOS','[0.5,2]','TRAIN.STEPSIZE','[50000]'],tag=None,weight='data/imagenet_weights/vgg16.ckpt')

以上這篇python入門:argparse淺析 nargs='+'作用就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。