我有一些按组分类的命令行参数如下:
cmdParser = argparse.ArgumentParser()
cmdParser.add_argument('mainArg')
groupOne = cmdParser.add_argument_group('group one')
groupOne.add_argument('-optA')
groupOne.add_argument('-optB')
groupTwo = cmdParser.add_argument_group('group two')
groupTwo.add_argument('-optC')
groupTwo.add_argument('-optD')
我如何解析上面的内容,以便最终得到三个不同的Namespace对象?
global_args - containing all the arguments not part of any group
groupOne_args - containing all the arguments in groupOne
groupTwo_args - containing all the arguments in groupTwo
谢谢!
答案 0 :(得分:3)
你可以这样做:
import argparse
parser = argparse.ArgumentParser()
group1 = parser.add_argument_group('group1')
group1.add_argument('--test1', help="test1")
group2 = parser.add_argument_group('group2')
group2.add_argument('--test2', help="test2")
args = parser.parse_args('--test1 one --test2 two'.split())
arg_groups={}
for group in parser._action_groups:
group_dict={a.dest:getattr(args,a.dest,None) for a in group._group_actions}
arg_groups[group.title]=argparse.Namespace(**group_dict))
这将为您提供正常的args,以及包含每个已添加组的名称空间的字典arg_groups。
(改编自this answer)
答案 1 :(得分:2)
argparse
中的任何内容都不是为了做到这一点。
对于它的价值,parser
从两个参数组开始,一个显示为positionals
,另一个显示为optionals
(我忘记确切的标题)。因此,在您的示例中,实际上将有4个组。
解析器仅在格式化帮助时使用参数组。对于解析,所有参数都放在主parser._actions
列表中。在解析过程中,解析器只传递一个命名空间对象。
您可以使用不同的参数集定义单独的解析器,并使用parse_known_args
调用每个解析器。使用optionals
(标记)参数比使用positionals
更好。它会破坏你的帮助。
我在其他SO问题中探讨过一个小小的Namespace
类,它可以基于某种虚线dest
(group1.optA
,group2.optC
等名称)来嵌套值。 。我不记得是否必须自定义Action
类。
基本点是,当将值保存到命名空间,解析器或实际上是Action
(参数)对象时:
setattr(namespace, dest, value)
那个(和getattr / hasattr)是解析器对namespace
所期望的全部。默认的Namespace
类很简单,只是普通的object
子类。但它可能更精细。
答案 2 :(得分:0)
很长时间以来,我一直在寻找解决方案,
我想我终于明白了。
所以我就把它放在这里...
from argparse import ArgumentParser
def _parse_args():
parser = ArgumentParser()
parser.add_argument('-1', '--flag-1', action='store_true', default=False)
parser.add_argument('-2', '--flag-2', action='store_true', default=False)
parser.add_argument('-3', '--flag-3', action='store_true', default=False)
args, unknown = parser.parse_known_args()
print(f"args : {args}")
print(f"unknown : {unknown}")
hidden = ArgumentParser(add_help=False)
hidden.add_argument('-d', '--debug', action='store_true', default=False)
hidden_args = hidden.parse_args(unknown)
print(f"hidden_args : {hidden_args}")
if __name__ == "__main__":
_parse_args()
结果:
显示帮助:
ubuntu → playAround $ ./test.py -h
usage: test.py [-h] [-1] [-2] [-3]
optional arguments:
-h, --help show this help message and exit
-1, --flag-1
-2, --flag-2
-3, --flag-3
带有调试标志:
ubuntu → playAround $ ./test.py -d
args : Namespace(flag_1=False, flag_2=False, flag_3=False)
unknown : ['-d']
hidden_args : Namespace(debug=True)
带有标志1和2:
ubuntu → playAround $ ./test.py -12
args : Namespace(flag_1=True, flag_2=True, flag_3=False)
unknown : []
hidden_args : Namespace(debug=False)
带有标志1和2并进行调试:
ubuntu → playAround $ ./test.py -12 -d
args : Namespace(flag_1=True, flag_2=True, flag_3=False)
unknown : ['-d']
hidden_args : Namespace(debug=True)
您无法使用此方法做的唯一事情是将debug short标志与其他short标志一起传递:
ubuntu → playAround $ ./test.py -12d
usage: test.py [-h] [-1] [-2] [-3]
test.py: error: argument -2/--flag-2: ignored explicit argument 'd'