是否可以在不使用子分析符的情况下表示一组argparse的参数?

时间:2017-02-22 19:33:15

标签: python argparse

我有一个argparser,有两个参数,输入和参数子集。我的命令看起来像

program -input1 <input1> -input2 <input2> -p1 <param1> -p2 <param2>

我喜欢

args = parser.parse_args()
params = vars(args.params)

而不是

params = {"p1": args.p1, "p2": args.p2, etc...}

有没有一种优雅的方式来做类似的事情:

parser.add_argument("-p1", dest='p1', part_of=params)

Subparsers似乎并不是为此而做的。或者是他们?

Argparse有argument groups,但他们似乎只是为了帮助文字。

谢谢!

1 个答案:

答案 0 :(得分:0)

这听起来像是一个变体 - 我如何接受任意&#39; key = value&#39;对?多年来,它以各种方式被问及各种答案。

最近的一篇:

Parsing "python foo.py -DVAR1=9 -DVAR2=Off" with argparse

我的解决方案是将-DVAR1=9拆分为('VAR1',9)并将其附加到D属性。这使用自定义type

Using variable arg names with argparse - 在将sys.argv传递给解析器之前对其进行处理。

python argparse store --foo=bar as args.key='foo', args.value='bar'

建议使用自定义Action类。

我认为我们还建议了一个自定义的Namespace课程。

用于对值进行分组的内置机制是nargsappend操作。您可以一起获取列表列表的属性。

JSON字符串也可用于输入复杂的数据结构。

class MyAction(argparse._StoreAction):
    def __call__(self, parser, namespace, values, option_string=None):
        print('storing', option_string)
        arg = getattr(namespace, self.dest)
        if arg is None:
            arg = {}
        arg[option_string] = values
        setattr(namespace, self.dest, arg)

In [135]: p=argparse.ArgumentParser()
In [136]: p.add_argument('--p1',action=MyAction,dest='p');
In [137]: p.add_argument('--p2',action=MyAction,dest='p');
In [138]: p.parse_args('--p1 one --p2 two'.split())
storing --p1
storing --p2
Out[138]: Namespace(p={'--p2': 'two', '--p1': 'one'})
In [139]: _.p
Out[139]: {'--p1': 'one', '--p2': 'two'}

显然,这可以通过各种方式进行改进 - 修剪键到#p1&#39;甚至&#39; 1&#39;,保存到列表,嵌套的命名空间或其他自定义结构等。

此方法仍需要为每个&#39; - pn`变体定义add_argument

另一种方法是保持argparse简单,产生如下命名空间:

In [141]: argparse.Namespace(p1='one', p2='two', input1=1, input2=3)
Out[141]: Namespace(input1=1, input2=3, p1='one', p2='two')

然后再进行自己的分组。

In [142]: args=argparse.Namespace(p1='one', p2='two', input1=1, input2=3)
In [143]: {key:getattr(args,key) for key in ['p1','p2']}
Out[143]: {'p1': 'one', 'p2': 'two'}