在 argparse 中,是否可能有来自多个父解析器的源互斥参数?
In argparse, is it possible to have source mutually exclusive args from multiple parent parsers?
下面将设置一个互斥组,其中“-a”或“-b”只有一个有效。
import argparse
parser = argparse.ArgumentParser()
group = parser.add_add_mutually_exclusive_group()
group.add_argument('-a')
group.add_argument('-b')
我想改为提供来自其他解析器的“-a”和“-b”参数。类似于:
a_parser = argparse.ArgumentParser()
a_parser.add_argument('-a')
b_parser = argparse.ArgumentParser()
b_parser.add_argument('-b')
parser = argparse.ArgumentParser()
group = parser.add_add_mutually_exclusive_group()
group.SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER(a_parser)
group.SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER(b_parser)
在这两种情况下,我希望以下内容会引发有关使用不兼容参数的异常:
parser.parse_args(['-a', '1', '-b', '1'])
问题是我不知道我缺少的“SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER”逻辑是否存在。如果它确实存在,我不知道该怎么做。有人有什么想法吗?
是的,有一种方法,但它使用了解析器的一些隐藏属性。我正在使用为
开发的想法
http://bugs.python.org/issue10984 argparse add_mutually_exclusive_group should accept existing arguments to register conflicts
使用 add_help=False
创建 2 个 parent 解析器(以防止 -h
参数发生冲突 - 这是标准的 parent 解析器过程)
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
,其他都是从parent继承的。我之前还保存了指向这些 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
returns 指向刚刚创建的 Action 的指针。
parents
通过仅复制动作点,即通过引用将动作添加到新解析器。
知道 parse
和 group
存储其相关操作列表的位置。
了解将动作添加到组与将其添加到解析器有何不同(不多)。
我建议在交互式 shell(如 IPython
)中测试这样的代码,您可以在其中查看 parser
和 group
的属性。并随身携带一份 Lib/argparse.py
。 :)
补丁 10984 添加了一些代码来处理在多个组中执行操作的复杂情况。通常一个动作只属于一个组。
下面将设置一个互斥组,其中“-a”或“-b”只有一个有效。
import argparse
parser = argparse.ArgumentParser()
group = parser.add_add_mutually_exclusive_group()
group.add_argument('-a')
group.add_argument('-b')
我想改为提供来自其他解析器的“-a”和“-b”参数。类似于:
a_parser = argparse.ArgumentParser()
a_parser.add_argument('-a')
b_parser = argparse.ArgumentParser()
b_parser.add_argument('-b')
parser = argparse.ArgumentParser()
group = parser.add_add_mutually_exclusive_group()
group.SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER(a_parser)
group.SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER(b_parser)
在这两种情况下,我希望以下内容会引发有关使用不兼容参数的异常:
parser.parse_args(['-a', '1', '-b', '1'])
问题是我不知道我缺少的“SOME_HOW_ADD_ARGS_FROM_OTHER_PARSER”逻辑是否存在。如果它确实存在,我不知道该怎么做。有人有什么想法吗?
是的,有一种方法,但它使用了解析器的一些隐藏属性。我正在使用为
开发的想法http://bugs.python.org/issue10984
argparse add_mutually_exclusive_group should accept existing arguments to register conflicts
使用 add_help=False
创建 2 个 parent 解析器(以防止 -h
参数发生冲突 - 这是标准的 parent 解析器过程)
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
,其他都是从parent继承的。我之前还保存了指向这些 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
returns 指向刚刚创建的 Action 的指针。parents
通过仅复制动作点,即通过引用将动作添加到新解析器。知道
parse
和group
存储其相关操作列表的位置。了解将动作添加到组与将其添加到解析器有何不同(不多)。
我建议在交互式 shell(如 IPython
)中测试这样的代码,您可以在其中查看 parser
和 group
的属性。并随身携带一份 Lib/argparse.py
。 :)
补丁 10984 添加了一些代码来处理在多个组中执行操作的复杂情况。通常一个动作只属于一个组。