允许在不同的argparser组中使用相同的选项

2 投票
2 回答
1013 浏览
提问于 2025-04-18 07:10

是否可以让同一个 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 个回答

1

在这个特殊情况下,你可以让 --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 的子解析器,或者干脆使用其他的命令行解析工具。

4

这个链接 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 中提到它。

撰写回答