参数组之间的互斥

4 投票
1 回答
3491 浏览
提问于 2025-04-18 08:02

我正在尝试使用argparse模块实现以下参数依赖关系:./prog [-h | [-v schema] file],这意味着用户必须传递-h或者一个文件。如果传递了文件,用户可以选择性地传递-v schema。

这是我现在的代码,但似乎不太管用:

import argparse

parser = argparse.ArgumentParser()
mtx = parser.add_mutually_exclusive_group()
mtx.add_argument('-h', ...)  
grp = mtx.add_argument_group()
grp.add_argument('-v', ...)
grp.add_argument('file', ...)   
args = parser.parse_args()

看起来你不能把参数组添加到互斥组里,还是我漏掉了什么?

1 个回答

5

如果 -h 是指默认的帮助信息,那你只需要这个(这个帮助信息已经很详细了)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file')
parser.add_argument('-s','--schema')
parser.parse_args('-h'.split())  # parser.print_help()

输出

usage: stack23951543.py [-h] [-s SCHEMA] file
...

如果你说的 -h 是指其他的操作,那我们可以把它改名为 -x。这样就更接近你描述的内容了

parser = argparse.ArgumentParser()
parser.add_argument('-s','--schema', default='meaningful default value')
mxg = parser.add_mutually_exclusive_group(required=True)
mxg.add_argument('-x','--xxx', action='store_true')
mxg.add_argument('file', nargs='?')
parser.parse_args('-h'.split())

用法是:

usage: stack23951543.py [-h] [-s SCHEMA] (-x | file)

现在 -x 或者 file 是必须的(但不能同时使用)。-s 是可选的,无论如何都有一个有意义的默认值,所以如果省略了也没关系。如果给了 -x,你可以直接忽略 -s 的值。

如果需要,你可以在解析后测试 args,确认如果 args.file 不是 None,那么 args.schema 也不能是 None。


之前我写过(可能想得太多了):

一个 argument_group 不能被添加到一个 mutually_exclusive_group 中。这两种组的目的和功能不同。之前有关于这个的讨论(见“相关”),还有一些相关的 Python bug 问题。如果你想要的测试超出了简单的互斥组,你可能需要在 parse_args 之后自己进行测试。这可能还需要你自己写一个 usage 行。

一个 argument_group 只是用来在帮助部分对参数进行分组和标记的工具。

mutually_exclusive_group 会影响 usage 的格式(如果可以的话),并且在 parse_args 时会进行测试。用“组”这个词来描述这两者,暗示它们之间的联系比实际要紧密得多。

http://bugs.python.org/issue11588 提出了嵌套组的请求,以及测试“包含性”的能力。我试图说明“组”这个概念并不足以表达用户想要的所有测试类型。但将测试机制进行概括是一回事,而设计一个直观的 API 又是另一回事。像这样的问题表明 argparse 确实需要某种“嵌套组”的语法。

撰写回答