如果你正确选择默认值,你可以在'parse_args'之后的'namespace'中轻松测试参数值的逻辑组合。你也可以在那时发出解析器错误。有一个错误报告要求互相包含的组。我在那里提出了一种添加广义组合测试机制的方法。但它仍然需要你自己进行逻辑测试。
http://bugs.python.org/issue11588
在argparse中添加“必须包含”组
我在这个问题中提出的解决方案的关键是使程序员可以使用
seen_non_default_actions
变量。这是一个已经看到的操作列表(实际上是一个集合),考虑到可选位置总是被“看到”的。我希望看到更多讨论如何实现包含和排除组合的混合。
你指定:
我有4个参数:-g,-wid,-w1和-w2。
-w1和-w2总是一起出现
-wid和(-w1 -w2)是互斥的,但其中一个是必需的
-g是可选的;如果没有指定,则只能出现(-w1 -w2),但不能出现-wid
我会尝试概括为:
complex_group('g', required_next_exclusive_group('wid', inclusive_group('w1','w2)))
"
w1
,w2
可以用'--w1w2',nargs=2
替换。简单的“mutually_inclusive_group”在这里可以起作用。但是argparse
无法处理嵌套组。
wid
和w1w2
可以放在必需的mutually_exclusive_group
中。
-g
需要像if args.g is None and args.wid is None: error()
这样的测试。
"
这里有一个脚本,它可以按照您的要求(我想是这样)运行,使用了我在Issue11588中的最新补丁。`act_w1`等是实际的操作对象,可能会出现在`seen_actions`列表中。测试函数已经在子解析器中注册,并在其`parse_know_args()`结束时执行。
parser = argparse.ArgumentParser(usage='custom usage')
sp = parser.add_subparsers(dest='cmd')
sp.required = True
spp = sp.add_parser('cmd1')
act_g = spp.add_argument('-g')
act_wid = spp.add_argument('--wid')
act_w1 = spp.add_argument('--w1')
act_w2 = spp.add_argument('--w2')
@spp.crosstest
def test1(spp, seen_actions, *args):
if 1==len({act_w1, act_w2}.intersection(seen_actions)):
parser.error('-w1 and -w2 always appear together')
@spp.crosstest
def test2(spp, seen_actions, *args):
if act_wid in seen_actions:
if act_w1 in seen_actions or act_w2 in seen_actions:
parser.error('-wid and (-w1 -w2) are mutually exclusive')
elif act_w1 not in seen_actions:
parser.error('wid or (w1 and w2) required')
@spp.crosstest
def test3(spp, seen_actions, *args):
if act_g not in seen_actions and act_wid in seen_actions:
parser.error('not g, so not wid')
args = parser.parse_args()
在这个例子中,我保存并测试操作对象的存在。也可以使用“dest”字符串进行测试。我正在探索使这种测试更直观和用户友好的方法。扩展的装饰器集合似乎是最有前途的。