argparse (python) 是否支持互斥的参数组? [英] Does argparse (python) support mutually exclusive groups of arguments?

查看:21
本文介绍了argparse (python) 是否支持互斥的参数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有参数 '-a', '-b', '-c', '-d',带有 add_mutually_exclusive_group() 函数我的程序将不得不只使用其中之一.有没有办法把它结合起来,让程序只接受 '-a 999 -b 999''-c 999 -d 999' ?>

添加一个更清晰的简单程序:

<预><代码>>>>解析器 = argparse.ArgumentParser()>>>group = parser.add_mutually_exclusive_group()>>>group.add_argument('-a')>>>group.add_argument('-b')>>>group.add_argument('-c')>>>group.add_argument('-d')

然后只有 ./app.py -a |./app.py -b |./app.py -c |./app.py -d 可以调用.是否可以将 argparse 分组为排除组,以便只有 ./app.py -a .. -b .. |./app.py -c .. -d .. 被调用?

解决方案

EDIT:没关系.因为 argparse 做出了在调用 group.add_argument 时必须创建选项的可怕选择.那不会是我的设计选择.如果您迫切需要此功能,可以尝试使用 ConflictsOptionParser:

# exclusivegroups.py导入冲突解析解析器 = 冲突冲突.ConflictsOptionParser()a_opt = parser.add_option('-a')b_opt = parser.add_option('-b')c_opt = parser.add_option('-c')d_opt = parser.add_option('-d')导入迭代工具compatible_opts1 = (a_opt, b_opt)compatible_opts2 = (c_opt, d_opt)独家 = itertools.product(compatible_opts1, compatible_opts2)对于exclusives中的exclusive_grp:parser.register_conflict(exclusive_grp)opts, args = parser.parse_args()打印选择:",选择打印 "args:", args

因此当我们调用它时,我们可以看到我们得到了想要的效果.

$ python exclusivegroups.py -a 1 -b 2选项:{'a':'1','c':无,'b':'2','d':无}参数:[]$ pythonexclusivegroups.py -c 3 -d 2选项:{'a':无,'c':'3','b':无,'d':'2'}参数:[]$ pythonexclusivegroups.py -a 1 -b 2 -c 3用法:exclusivegroups.py [选项]exclusivegroups.py:错误:-b、-c 是不兼容的选项.

警告消息不会通知您 '-a''-b''-c' 不兼容,但是可以制作更合适的错误消息.旧的,下面的错误答案.

旧版 [这个编辑是错误的,尽管如果 argparse 以这种方式工作,它会不会只是一个完美的世界?]我之前的答案实际上是不正确的,您应该能够通过为每个互斥选项指定一组来使用 argparse 来做到这一点.我们甚至可以使用 itertools 来概括这个过程.并做到这一点,以便我们不必明确输入所有组合:

import itertoolscompatible_opts1 = ('-a', '-b')compatible_opts2 = ('-c', '-d')独家 = itertools.product(compatible_opts1, compatible_opts2)对于exclusives中的exclusive_grp:group = parser.add_mutually_exclusive_group()group.add_argument(exclusive_grp[0])group.add_argument(exclusive_grp[1])

If I have the arguments '-a', '-b', '-c', '-d', with the add_mutually_exclusive_group() function my program will have to use just one of them. Is there a way to combine that, so that the program will accept only either '-a 999 -b 999' or '-c 999 -d 999'?

Edit: adding a simple program for more clarity:

>>> parser = argparse.ArgumentParser()
>>> group = parser.add_mutually_exclusive_group()
>>> group.add_argument('-a')
>>> group.add_argument('-b')
>>> group.add_argument('-c')
>>> group.add_argument('-d')

Then only ./app.py -a | ./app.py -b | ./app.py -c | ./app.py -d can be called. Is it possible to have argparse group the exclusion groups, so that only ./app.py -a .. -b .. | ./app.py -c .. -d .. be called?

解决方案

EDIT: Never mind. Because argparse makes the horrible choice of having to create an option when invoking group.add_argument. That wouldn't be my design choice. If you're desperate for this feature, you can try doing it with ConflictsOptionParser:

# exclusivegroups.py
import conflictsparse

parser = conflictsparse.ConflictsOptionParser()
a_opt = parser.add_option('-a')
b_opt = parser.add_option('-b')
c_opt = parser.add_option('-c')
d_opt = parser.add_option('-d')

import itertools
compatible_opts1 = (a_opt, b_opt)
compatible_opts2 = (c_opt, d_opt)
exclusives = itertools.product(compatible_opts1, compatible_opts2)
for exclusive_grp in exclusives:
    parser.register_conflict(exclusive_grp)


opts, args = parser.parse_args()
print "opts: ", opts
print "args: ", args

Thus when we invoke it, we can see we get the desired effect.

$ python exclusivegroups.py -a 1 -b 2
opts:  {'a': '1', 'c': None, 'b': '2', 'd': None}
args:  []
$ python exclusivegroups.py -c 3 -d 2
opts:  {'a': None, 'c': '3', 'b': None, 'd': '2'}
args:  []
$ python exclusivegroups.py -a 1 -b 2 -c 3
Usage: exclusivegroups.py [options]

exclusivegroups.py: error: -b, -c are incompatible options.

The warning message doesn't inform you that both '-a' and '-b' are incompatible with '-c', however a more appropriate error message could be crafted. Older, wrong answer below.

OLDER EDIT: [This edit is wrong, although wouldn't it be just a perfect world if argparse worked this way?] My previous answer actually was incorrect, you should be able to do this with argparse by specifying one group per mutually exclusive options. We can even use itertools to generalize the process. And make it so we don't have to type out all the combinations explicitly:

import itertools
compatible_opts1 = ('-a', '-b')
compatible_opts2 = ('-c', '-d')
exclusives = itertools.product(compatible_opts1, compatible_opts2)
for exclusive_grp in exclusives:
    group = parser.add_mutually_exclusive_group()
    group.add_argument(exclusive_grp[0])
    group.add_argument(exclusive_grp[1])

这篇关于argparse (python) 是否支持互斥的参数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆