是否argparse提供内置工具让它将组或解析器解析到它们自己的命名空间中?我觉得我一定是在某处遗漏了一个选项。
编辑:这个例子可能不是我应该做的来构建解析器来满足我的目标,但这是我到目前为止所做的。我的具体目标是能够为子解析器提供解析为命名空间字段的选项组。我和 parent 的想法只是为了同样的目的使用通用选项。
例子:
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 将某些组解析为命名空间字段?
最佳答案
如果重点只是将选定的参数放在它们自己的 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
名称的方法有很多种。它可以在定义 Action 时作为参数传递。它可以作为参数添加。这里我选择从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)
关于python - 带有嵌套命名空间的 argparse 子命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18668227/