【发布时间】:2018-08-01 05:30:43
【问题描述】:
我有一些代码可以解析一个名为“blah.py”的文件中的一些参数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('opt', nargs='?')
parser.add_argument('--bool', action='store_true')
parser.add_argument('value')
args = parser.parse_args()
如果我这样称呼这个文件:
blah.py a b --bool
它工作正常(opt='a', value='b', bool=True)。
但是,如果我以不同的顺序调用它:
blah.py a --bool b
我希望得到相同的结果,但 argparse 模块正在打印 error: unrecognized arguments: b 消息。这是 argparse 模块的错误吗?为什么它会以这种方式工作?在我为脚本定义 CLI 时,我可以做些什么来避免遇到此类问题?
由于我的接口比示例复杂得多(具有子命令和更多参数),我有多种调用接口的方法,这要求某些参数对于某些调用是可选的,但对于其他调用是必需的。我计划手动验证这些情况,并在出错时调用 parser.print_usage 并退出。
【问题讨论】:
-
撇开历史不谈:用于命令行解析的 POSIX 规则指定选项 always 位于位置参数之前(请参阅 pubs.opengroup.org/onlinepubs/9699919799/basedefs/… 中的准则 9),因此任何值在 a非选项(和非选项参数)可以被认为是位置的(“操作数”而不是“选项”或“选项参数”)。教导用户他们可以随意混合选项和位置参数在很大程度上是 GNU 项目的错……但这是 optparse 和 argparse 一直存在的东西,所以我们在这里。 :-/
-
仅供参考,如果您在没有任何参数或使用
-h的情况下运行 argparse 命令,您将看到如下用法示例:blah.py [-h] [--bool] [opt] value从而向您显示它期望选项和参数的位置。 -
通常 argparse 允许任何顺序的参数。但是当位置之一是
?时,在中间混合一个标记的选项会导致问题。因此,要么将位置保持在一起(在结尾或开头),要么使用新的intermixed解析器。 -
@CharlesDuffy 感谢历史,如果我需要更改建议的调用,我想我最好遵循约定。 :)
-
我使用的是 3.6,但是已经从 3.7 下载了
argparse进行测试。这是一个独立的文件,因此可以在早期的发行版中使用。