2016-01-21 81 views
2

我正在爲需要能夠接受一個或多個選項組的命令行程序設計用戶界面。各組是一樣的,但需要連在一起,就像這樣:使用argparse對未知數量的參數進行分組

./myprogram.py --group1 name1,name2,pathA,pathB --group2 name3,name4,pathC,pathD 

這看起來非常笨重的用戶來處理。我曾考慮過使用INI樣式的configparser設置,但它也很笨拙,因爲除此之外我還有很多其他參數通常都有默認值,然後我失去了處理需求的所有模塊的功能,檢查如果文件存在等。

有沒有人有任何想法,我怎麼能最好的結構我的ArgumentParser,以便我可以讓用戶一起提供給定組的四個所需的輸入?我沒有和逗號分隔列表結婚,這只是一個例子。它實際上會好得多,如果他們能夠進入某種鍵值對,如

./myprogram.py --group1 firstname:name1 secondname:name2 firstpath:pathA secondpath:pathB 

但我知道,argparse不支持dict類型,任何黑客,使這將是用戶甚至更少-友善。

回答

3

可以使用nargs=4'append'動作:

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('--group', nargs=4, action='append') 

print parser.parse_args() 

它會被稱爲:

$ python ~/sandbox/test.py --group 1 2 3 4 --group 1 2 3 4 
Namespace(group=[['1', '2', '3', '4'], ['1', '2', '3', '4']]) 

從這裏,你可以解析鍵值對,如果你想。


另一種選擇是使用自定義動作做解析 - 這裏有一個簡單的一個,其接受--group key:value key2:value2 ... --group ...

import argparse 

class DictAction(argparse.Action): 
    def __init__(self, *args, **kwargs): 
     super(DictAction, self).__init__(*args, **kwargs) 
     self.nargs = '*' 

    def __call__(self, parser, namespace, values, option_string=None): 
     # The default value is often set to `None` rather than an empty list. 
     current_arg_vals = getattr(namespace, self.dest, []) or [] 
     setattr(namespace, self.dest, current_arg_vals) 
     arg_vals = getattr(namespace, self.dest) 
     arg_vals.append(dict(v.split(':') for v in values)) 

parser = argparse.ArgumentParser() 
parser.add_argument('--group', action=DictAction) 

print parser.parse_args() 

這有沒有檢查形式的參數(這樣用戶可以胡來TypeError如果key:value未正確格式化),並且如果您想將其限制爲指定的鍵,則需要將其構建爲...但這些細節應該足夠容易添加。您也可以要求他們使用self.nargs = 4DictAction.__init__中提供4個值。

+0

我喜歡這個,我沒有意識到action = append可以像那樣工作。我仍然認爲鍵值部分會有點難看,但命令行輸入很難開始。 –

+0

@IanFiddes - 我已經添加了一個key:value解析示例。 – mgilson