繁体   English   中英

Python argparse:复杂参数解析场景

[英]Python argparse: Complex Argument Parsing Scenario

我想实现以下命令行参数解析方案:

我有4个参数: -g-wid-w1-w2

-w1-w2总是同时出现

-wid(-w1 -w2)是互斥的,但是需要一个或另一个

-g是可选的; 如果未指定(-w1 -w2)可以出现,但不是-wid

有没有一种优雅的方法来实现这个使用argparse,但没有子命令(我已经在子命令中)?

我在考虑自定义操作,但是在我最后一次调用它时需要知道的操作体内(即当解析最后一个参数时),我不知道该怎么做数字和参数的顺序可能会有所不同。

以下是一些更多的解释:我正在编写的工具使用小部件和小工具参数-g创建小工具。 窗口小部件是一个已经存在的插件-然后它是由它的id称作-wid ,或正在使用的参数创建一个新的小部件-w1-w2 如果未指定-g则该工具将使用(-w1 -w2)创建并存储新窗口小部件,而不创建小工具。

先感谢您。

如果正确选择默认值,则可以在'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)))

w1w2可以替换为'--w1w2',nargs=2 一个简单的'mutual_inclusive_group'可以在这里工作。 但是argparse无法处理嵌套组。

widw1w2可以放在一个需要mutually_exclusive_group

-g需要进行测试, if args.g is None and args.wid is None: error()


这是一个脚本,根据您的需要(我认为),使用我在Issue11588中的最新补丁。 act_w1等是实际的操作对象,可能出现在seen_actions列表中。 测试函数在subparser中注册,并在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 # decorator to register this function with spp
def test1(spp, seen_actions, *args):
    # seen_actions - list of actions that were seen by parser
    if 1==len({act_w1, act_w2}.intersection(seen_actions)):
        # error if only one of these was seen
        parser.error('-w1 and -w2 always appear together')
@spp.crosstest
def test2(spp, seen_actions, *args):
    # required mutually exclusive wid and (w1,w2 group)
    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):
    # is this the simplest logical way of expressing this?
    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字符串进行测试。 我正在探索使这种测试更直观和用户友好的方法。 一组扩展的装饰者似乎最有希望。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM