2013-04-07 43 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]