我有一个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,但他们似乎只是为了帮助文字。
谢谢!
答案 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
课程。
用于对值进行分组的内置机制是nargs
和append
操作。您可以一起获取列表列表的属性。
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'}