当前位置: 首页 > 面试题库 >

带有嵌套名称空间的argparse子命令

顾涵衍
2023-03-14
问题内容

argparse是否提供用于将组或解析器解析到其自己的名称空间的内置工具?我觉得我一定在某个地方缺少选择。

编辑
:此示例可能不完全是我为构造解析器以满足我的目标而应该做的事情,但这是我到目前为止的工作。我的特定目标是能够为子解析器提供选项组,这些选项组被解析为名称空间字段。我与父母的想法只是出于相同的目的使用通用选项。

例:

import argparse

# Main parser
main_parser = argparse.ArgumentParser()
main_parser.add_argument("-common")

# filter parser
filter_parser = argparse.ArgumentParser(add_help=False)
filter_parser.add_argument("-filter1")
filter_parser.add_argument("-filter2")

# sub commands
subparsers = main_parser.add_subparsers(help='sub-command help')

parser_a = subparsers.add_parser('command_a', help="command_a help", parents=[filter_parser])
parser_a.add_argument("-foo")
parser_a.add_argument("-bar")

parser_b = subparsers.add_parser('command_b', help="command_b help", parents=[filter_parser])
parser_b.add_argument("-biz")
parser_b.add_argument("-baz")

# parse
namespace = main_parser.parse_args()
print namespace

这显然是我得到的:

$ python test.py command_a -foo bar -filter1 val
Namespace(bar=None, common=None, filter1='val', filter2=None, foo='bar')

但这就是我真正追求的:

Namespace(bar=None, common=None, foo='bar', 
          filter=Namespace(filter1='val', filter2=None))

然后,更多的选项组已经解析为名称空间:

Namespace(common=None, 
          foo='bar', bar=None,  
          filter=Namespace(filter1='val', filter2=None),
          anotherGroup=Namespace(bazers='val'),
          anotherGroup2=Namespace(fooers='val'),
          )

我在这里找到了一个相关的问题,但它涉及一些自定义解析,似乎只涵盖了一个非常具体的情况。

是否有选项告诉argparse将某些组解析为命名空间?


问题答案:

如果重点只是将选定的参数放入自己的参数中namespace,并且使用了次级解析器(和父级)是问题的附带原因,则此自定义操作可能会解决问题。

class GroupedAction(argparse.Action):    
    def __call__(self, parser, namespace, values, option_string=None):
        group,dest = self.dest.split('.',2)
        groupspace = getattr(namespace, group, argparse.Namespace())
        setattr(groupspace, dest, values)
        setattr(namespace, group, groupspace)

有多种指定group名称的方法。定义操作时,可以将其作为参数传递。可以将其添加为参数。在这里,我选择从解析dest(因此namespace.filter.filter1可以获取的值filter.filter1

# Main parser
main_parser = argparse.ArgumentParser()
main_parser.add_argument("-common")

filter_parser = argparse.ArgumentParser(add_help=False)
filter_parser.add_argument("--filter1", action=GroupedAction, dest='filter.filter1', default=argparse.SUPPRESS)
filter_parser.add_argument("--filter2", action=GroupedAction, dest='filter.filter2', default=argparse.SUPPRESS)

subparsers = main_parser.add_subparsers(help='sub-command help')

parser_a = subparsers.add_parser('command_a', help="command_a help", parents=[filter_parser])
parser_a.add_argument("--foo")
parser_a.add_argument("--bar")
parser_a.add_argument("--bazers", action=GroupedAction, dest='anotherGroup.bazers', default=argparse.SUPPRESS)
...
namespace = main_parser.parse_args()
print namespace

我必须添加,default=argparse.SUPPRESS因此bazers=None条目不会出现在主命名空间中。

结果:

>>> python PROG command_a --foo bar --filter1 val --bazers val
Namespace(anotherGroup=Namespace(bazers='val'), 
    bar=None, common=None, 
    filter=Namespace(filter1='val'), 
    foo='bar')

如果需要嵌套名称空间中的默认条目,则可以事先定义名称空间:

filter_namespace = argparse.Namespace(filter1=None, filter2=None)
namespace = argparse.Namespace(filter=filter_namespace)
namespace = main_parser.parse_args(namespace=namespace)

结果与以前一样,除了:

filter=Namespace(filter1='val', filter2=None)


 类似资料:
  • 这是一个非常基本的问题,但实际上我从来没有自己定义过名称空间。我正在尝试将我的基于Qt的库中的类分组在各种名称空间中(并且还允许更容易的扩展而不发生名称冲突)。例如,主类(也表示库)属于顶级命名空间: 这个使用了一组其他名称空间和类,这些名称空间和类是在的头文件中定义的,这些头文件包含在的头文件中: 其中Manager.h包含 和configurator.h包含 类的内容在这里并不重要。 在编译时

  • 问题内容: 我正在实现一个命令行程序,其界面如下: 我已经阅读了argparse文档。我可以使用in实现为可选参数。以及using子命令。 从文档看来,我只能有一个子命令。但是如您所见,我必须实现一个或多个子命令。解析此类命令行参数使用的最佳方法是什么? 问题答案: @mgilson对这个问题有很好的答案。但是我自己拆分sys.argv的问题是我丢失了Argparse为用户生成的所有有用的帮助消息

  • 问题内容: 以下是我应从Java Web应用程序调用的.NET Web服务的通用SOAP请求示例: 我可以使用以下代码段从Java控制台应用程序生成类似的内容: 结果是以下XML: 这将调用服务。接下来,我使用 soapUI 尝试调用此服务,并像这样从WSDL生成了soap消息(它 与 前面的信封和前缀中的名称空间声明 不同 ): 这也可以在soapUI中使用。但是最后,当我尝试使用以下代码序列重

  • 我使用JAXB从SOAP响应中解析xml元素。我已经为xml元素定义了POJO类。我已经测试了没有名称空间和前缀的pojo类,它工作得很好。需求是解析来自SOAPMessage对象的输入

  • 问题内容: 如何执行路径名中包含空格的Java System(shell)命令? 我尝试将引号和反斜杠()放在一起,但这不起作用。 问题答案: 到目前为止,最可靠的方法是使用Runtime.exec(String [] cmdarray) 。 如果使用Runtime.exec(String command) ,则Java仅在空白处分割命令。 使用调用new StringTokenizer(comm