允许在不同的argparser组中使用相同的选项
是否可以让同一个 argparse 选项出现在两个不同的 argparser 组里?
其实我想达到的效果是这样的:
#!/usr/bin/env python
import argparse
... ... ...
g1 = parser.add_argument_group('g1')
g2 = parser.add_argument_group('g2')
g1.add_argument('--aa')
g1.add_argument('--common')
g2.add_argument('--bb')
g2.add_argument('--common')
... 然后打印出来的帮助信息看起来是这样的:
usage: ...
... ... ...
g1:
--aa [aa]
--common [common]
g2:
-bb [bb]
--common [common]
但是这是不可能的,因为 argparse 会报错说“选项字符串冲突”。
2 个回答
在这个特殊情况下,你可以让 --aa 和 --bb 这两个选项互相排斥。
import argparse
parser = argparse.ArgumentParser()
mutex = parser.add_mutually_exclusive_group()
mutex.add_argument('--aa', action = 'store_true')
mutex.add_argument('--bb', action = 'store_true')
parser.add_argument('--common', action = 'store_true')
args = parser.parse_args()
这样就会得到
usage: a.py [-h] [--aa | --bb] [--common]
一般来说,argparse 这个工具有个问题,就是在调用 add_argument 的时候,你必须创建一个选项。
这里有个相关的话题:argparse(python)是否支持互斥的参数组?
还有一个补丁可以让你在多个互斥组中使用同一个参数:http://bugs.python.org/issue10984
你还可以尝试使用 argparse 的子解析器,或者干脆使用其他的命令行解析工具。
这个链接 http://bugs.python.org/issue10984 讨论了如何给两个不同的 mutually_exclusive_groups
添加一个参数。对 argument_groups
做同样的事情也可以,但相对简单一些。
import argparse
parser=argparse.ArgumentParser()
g1=parser.add_argument_group('group1')
g1.add_argument('-a')
caction=g1.add_argument('-c')
g2=parser.add_argument_group('group2')
g2.add_argument('-b')
g2._group_actions.append(caction)
parser.print_help()
这有点像是个临时解决办法,因为它在修改一个组的“私有”属性。
结果是:
usage: ipython [-h] [-a A] [-c C] [-b B]
optional arguments:
-h, --help show this help message and exit
group1:
-a A
-c C
group2:
-b B
-c C
现在来看看发生了什么。add_argument
会创建一个 Action
,把它注册到 parser
中,并返回这个动作。这就是 caction
捕获到的内容。如果把这个动作添加到一个组里,它也会把这个动作注册到组中——通过把它放到一个 _group_actions
列表里。
如果你执行 g2.add_argument('-c')
,你会得到一个错误,因为解析器已经有一个带有这个选项字符串的动作。你“添加”到不同组的事实并不重要。这个临时解决办法通过把它添加到组的列表中,避免了创建一个新的动作。
如果从文档中看不出来,argument_groups
基本上就是一个“帮助”方便工具。它们完全不影响解析过程。你还有其他方法可以自定义 help
。比如,可以在 parser
中添加 --common
,可能还带有一个 SUPPRESS
的帮助行。然后在每个组的 description
中提到它。