2013-04-07 55 views
5

我知道,將多個位置參數放到一個互斥組中是沒有意義的,因爲你不能說誰是誰。但是我需要在其中包含一個位置參數。如何在argparse互斥組中包含一個位置參數?

我需要什麼:

$ myprogram -h 
usage: myprogram [-h] [--delete value | --update value | value] 

凡位置value是(的 「--include」 的那種)的默認操作。 (無參數的myprogram也必須是有效的)。

我第一次嘗試(不工作):

parser = ArgumentParser() 
group = parser.add_mutually_exclusive_group() 
group.add_argument('--delete', metavar='value') 
group.add_argument('--update', metavar='value') 
group.add_argument('value') 

這可能嗎?


第二次嘗試:

parser = ArgumentParser() 
group = parser.add_mutually_exclusive_group() 
group.add_argument('--delete', action='store_true') 
group.add_argument('--update', action='store_true') 
group.add_argument('--insert', action='store_true', default=True) 
group.add_argument('value') 

回答

8

我應該這樣做有點不同:

parser = ArgumentParser() 
group = parser.add_mutually_exclusive_group() 
group.set_defaults(mode='insert') 
group.add_argument('--delete', action='store_const', dest='mode', const='delete') 
group.add_argument('--update', action='store_const', dest='mode', const='update') 
group.add_argument('--insert', action='store_const', dest='mode', const='insert') 
parser.add_argument('value', nargs='?') 
args = parser.parse_args() 

如果你還想讓program --delete(無value選項)失敗,加上

if args.mode != 'insert' and args.value: 
    parser.error("can't {} without a value argument".format(args.mode)) 

注意,這將意味着, program --insert(沒有value)仍然有效。您可以通過使默認modeNone稍微多一些努力來避免此問題,使用args.mode is not None進行上面的檢查,然後執行if args.mode is None: args.mode = 'insert'或類似操作。

+0

+1好方法 – msw 2013-04-07 15:51:36

3

你的語法更清晰地描述爲:

myprogram {--insert|--update|--delete} value 

在需要--insert默認值爲True和價值。

​​可以讓你感覺像你期望的語法必須符合它的模型時,像

if args.insert and (args.update or args.delete): 
    parser.print_help() 

更加明顯。

新增迴應評論:

這裏是一個展示我將如何實現這個僞代碼(意思是我沒有測試):

parser.add_argument('--insert', action='store_true') 
parser.add_argument('--update', action='store_true') 
parser.add_argument('--delete', action='store_true') 
parser.add_argument('value') 
args = parser.parse_args(sys.argv) 
if ((args.insert and args.delete) or 
    (args.insert and args.update) or 
    (args.update and args.delete)): 
    # can't pick more than one, complain and quit 
elif not (args.update or args.delete): 
    # they specified no action so assume insert 
    args.insert = True 

# now one and only one of insert/update/delete is 
# True and args.value contains the argument 

我希望讓事情更清晰。

+0

謝謝您的回答,但我沒有完全理解你:我沒添加「 - 插入'參數並將默認設置爲True。所以,這部分工作。但是調用沒有參數的'myprogram'失敗,因爲'value'是必需的。也許我根本不理解你...... – borges 2013-04-07 15:18:33

+0

請用新的代碼更新你的問題或者打開一個新的問題,因爲我看不懂我看不到的東西。我懷疑你試圖保留不需要的互斥分組。 – msw 2013-04-07 15:21:53

+0

我更新了問題。 – borges 2013-04-07 15:26:08

3

設爲可選的位置參數

parser = ArgumentParser() 
group = parser.add_mutually_exclusive_group() 
group.add_argument('--delete', metavar='value') 
group.add_argument('--update', metavar='value') 
group.add_argument('value', nargs='?') 

用法,然後(與「?」):

usage: ipython [-h] [--delete value | --update value | value]