是的,有一种方法,但它使用了解析器的一些隐藏属性。我正在使用为
开发的想法
http://bugs.python.org/issue10984argparse add_mutually_exclusive_group should accept existing arguments to register conflicts
使用 add_help=False 创建 2 个父解析器(以防止 -h 参数发生冲突 - 这是标准父解析器过程)
a_parser = argparse.ArgumentParser(add_help=False)
aaAction = a.parser.add_argument('-a')
b_parser = argparse.ArgumentParser(add_help=False)
bbAction = b_parser.add_argument('-b')
parser=argparse.ArgumentParser(parents=[a_parser, b_parser])
group=parser.add_mutually_exclusive_group()
此时parser有3个动作(参数),可以在一个'private'属性中看到,_actions:
print parser._actions
"""
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['-a'], dest='a', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None),
_StoreAction(option_strings=['-b'], dest='b', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
"""
第一个是它自己的help,其他的都是从父母那里继承的。我还保存了指向这些的指针,aaAction 和 bbAction。现在我们只需要将这些添加到group 的_group_actions 列表中:
group._group_actions.append(parser._actions[1]) # or (aaAction)
group._group_actions.append(parser._actions[2]) # or (bbAction)
如果补丁 10984 已经实现,我们可以编写:
group = parser.add_mutually_exclusive_group(aaAction, bbAction)
这将作为创建组的一部分执行此附加。
我们可以测试它:
In [31]: print parser.format_help()
usage: ipython [-h] [-a A | -b B]
optional arguments:
-h, --help show this help message and exit
-a A
-b B
In [32]: parser.parse_args(['-a','a'])
Out[32]: Namespace(a='a', b=None)
In [33]: parser.parse_args(['-a','a','-b','b'])
usage: ipython [-h] [-a A | -b B]
ipython: error: argument -b: not allowed with argument -a
An exception has occurred, use %tb to see the full traceback.
这取决于几条信息:
add_argument 返回一个指向它刚刚创建的 Action 的指针。
parents 仅通过复制动作点(即通过引用)将动作添加到新解析器。
知道parse 和group 将它们的相关操作列表存储在哪里。
了解将动作添加到组与将其添加到解析器有何不同(不多)。
我建议在交互式 shell(如 IPython)中测试这样的代码,您可以在其中查看 parser 和 group 的属性。并随身携带一份Lib/argparse.py 的副本。 :)
patch 10984 添加了一些代码来处理在多个组中执行操作的复杂性。通常一个动作只属于一个组。