【发布时间】:2013-09-11 04:06:06
【问题描述】:
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'),
)
我找到了related question here,但它涉及一些自定义解析,似乎只涵盖了一个非常具体的情况。
是否有一个选项可以告诉 argparse 将某些组解析为命名空间字段?
【问题讨论】:
-
我不确定您希望它如何工作。正如您所写,
filter1和filter2位于顶级解析器中,而不是位于某些名为filter的子解析器中。 argparse 怎么知道你希望它充当每个子解析器的子解析器,而实际上它不是? -
@abarnert:我可能应该根据您的问题重新格式化我的示例。因为正如你所指出的那样,我放在一起的结构确实不合适。我的目标确实是能够将选项组应用于子解析器,并将它们解析到命名空间中。如果它们可以通用就好了,这就是我尝试使用父结构的原因。
-
所以你正在寻找类似
pip、git等的东西,除了顶级全局选项和特定于每个子命令的选项外,还有共享选项通过多个不同的子命令(例如,pip的--verbose、--upgrade和--user选项),并且能够直接表示该共享而不是使其隐式(通过将选项组复制到多个子解析器)? -
或者您只是想要
add_argument_group所做的事情(并且您可以复制组),除了您希望分组的参数出现在结果中的子命名空间中?因为使用后处理器很容易做到这一点:为每个组创建一个子命名空间,迭代主命名空间,以及作为组成员的每个参数,将其移动到子命名空间。但是,如果你也需要的话,使用子解析器会更复杂一些。 -
@abarnert:是的,你是对的。我应该使用一个参数组,并在事后进行后期处理。感谢您的回答!
标签: python namespaces argparse