Python argparse互斥参数

4
我该如何让argparse做类似以下的事情:
[ 'all' | [ pos1 [ pos2 [ pos3 ...]]]] --some --other --flags

其中all是一个保留字,(如果不需要-前缀,则将其作为标志不可行)

第二点: 是否可以为命名参数添加一些别名,例如-h--help表示相同的选项?也许我应该尝试使用add_mutually_exclusive_group()

1个回答

4

add_mutually_exclusive_group()的设计正是为此而来 - 您正在尝试添加一个互斥组。

关于您问题的第二部分,这应该可以满足您的需求:

parser.add_argument('-f', '--foobar')

(注意:你的问题有点混乱——其中有两个问题,第二个问题直接进入了关于第一个问题的另一句话。更不用说那些错别字了……我会尽力帮助你,但你能让问题更清晰,我们就能更清晰地回答你。)
更新 据我所知,互斥参数必须被要求,但位置参数不能被要求。因此,位置参数不能是互斥的(可能是因为否则解释器无法分辨哪个是哪个)。对于你的目的,我认为这并不重要,因为解释你的参数的代码无论哪种方式都几乎相同。
假设你可以按照你试图的方式做到这一点,然后必须像这样做:
# all == True  
# pos == ('this', 'that', 'theother')

if all == true:
    do_some_stuff('all')
else:
    do_some_other_stuff('positional arguments')

如果您将“all”作为您的位置参数之一,则需要执行以下操作:
# pos = ('all', 'this, 'that', 'theother')

if pos[0] == 'all': #other parameters are ignored
    do_some_stuff('all')
else:
    do_some_other_stuff('positional arguments')

除非您有特定的原因,否则我认为没有理由不采用后一种方法。

所以,'all' 应该是一个标志参数,而 'pos' 是一个位置参数,两者都应该进入互斥组?抱歉,但这并不能解决问题。位置参数和标志参数似乎没有进入同一组。 我还不断收到“ValueError:互斥参数必须是可选的”的错误提示。 - michael
1
逻辑上互斥的参数必须是可选的。如果其中一个是强制性的,则它们不再是互斥的。您确定两个参数都设置为可选吗?如果这听起来很显然,那么请原谅! - Mr_Chimp
嗯...也许我没有正确解释问题。让我们退一步。 我想接受0到n个位置参数。 如果第一个“位置”参数是保留字'all',我不想再接受其他位置参数。在任何情况下,我都接受标志或命名参数。我在argparse中找不到实现这一点的方法。当然,我可以通过稍后检查位置参数列表的内容来实现它。 - michael
第二个示例是我实际实现的。如果在解析参数时,我可以拒绝“all”情况下的额外位置参数,那就太好了。这里是代码: parser.add_argument('modules', metavar='MOD', nargs='*', help="模块列表或'all'") parser.add_argument('-s','--recursive', dest='recursive',action='store_true', help='递归') ... ... if len(args.modules) == 0: ... elif len(args.modules) == 1 and args.modules[0].lower() == 'all': ... else: for d in args.modules:
...
- michael
啊...你的意思是实际上引发一个错误,而不是默默地忽略它们?虽然可能需要自己实现,但应该可以让argparse引发一个错误...你引起了我的兴趣!我刚刚下班了,但我会在今晚或明天尽力帮助你。 - Mr_Chimp
从argparse.ArgumentParser派生?我认为人们没有这样的意图。我宁愿坚持使用官方API,因为任何其他解决方案可能在下一个版本中不稳定。也许使用ArgumentParser.parse_known_args进行多阶段解析可以提供答案?此外,子命令看起来很有趣,其中“all”可以是子命令。 - michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接