Python argparse:如何分别获取参数组的命名空间对象?

2024-10-04 07:37:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些命令行参数分组如下:

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')

如何解析上面的内容,从而得到三个不同的名称空间对象?在

^{pr2}$

谢谢你!在


Tags: 命令行add参数groupargparseargumentoneargumentparser
3条回答

argparse中的任何内容都不能做到这一点。在

不管怎样,parser从两个参数组开始,一个显示为positionals,另一个显示为optionals(我忘记了确切的标题)。所以在你的例子中,实际上有4个组。在

解析器仅在格式化帮助时使用参数组。对于解析,所有参数都放在主parser._actions列表中。在解析过程中,解析器只传递一个命名空间对象。在

您可以使用不同的参数集定义单独的解析器,并用parse_known_args调用每个解析器。与optionals(标记的)参数一起使用比使用positionals更好。你的帮助也就支离破碎了。在

我在其他的SO问题中探讨了一个新颖的Namespace类,它可以基于某种虚线dest(名称如group1.optAgroup2.optC,等等)嵌套值。我不记得是否必须定制Action类。在

基本点是,当将值保存到名称空间时,解析器或实际上是Action(argument)对象会:

setattr(namespace, dest, value)

这(和getattr/hasattr)就是解析器对namespace的全部期望。默认的Namespace类很简单,只不过是一个普通的object子类。但它可能会更精细。在

很久以来,我一直在寻找解决方案 我想我终于拿到了。
所以我就把它放在这里。。。在

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()

结果:
显示帮助:

^{pr2}$

带调试标志:

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标志传递给其他短标志:

ubuntu → playAround $ ./test.py -12d
usage: test.py [-h] [-1] [-2] [-3]
test.py: error: argument -2/ flag-2: ignored explicit argument 'd'

你可以这样做:

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)

这将为您提供普通的arg,以及包含每个添加组的名称空间的dictionary arg_组。在

(改编自this answer

相关问题 更多 >