带有可选子命令的 argparse 未按预期工作

Posted

技术标签:

【中文标题】带有可选子命令的 argparse 未按预期工作【英文标题】:argparse with optional subcommands not working as expected 【发布时间】:2021-11-13 02:06:41 【问题描述】:

使用python 3.9.5版本我遇到了以下代码sn-p的问题:

import argparse


parser = argparse.ArgumentParser()

subparsers = parser.add_subparsers(required=False)
sub_parser = subparsers.add_parser("sub")

parser.add_argument("global-argument")

args = parser.parse_args()

运行不带参数的 python 示例,会导致以下错误消息:

$ python3 main.py
usage: main.py [-h] sub ... global-argument
main.py: error: the following arguments are required: global-argument

错误信息显示只有全局参数是必需的,子命令是可选的。

但是使用 global 参数运行 python 示例,会导致以下错误消息:

$ python3 main.py global
usage: main.py [-h] sub ... global-argument
main.py: error: invalid choice: 'global' (choose from 'sub')

所以如果没有子命令(应该是可选的)就不可能提供全局参数?

【问题讨论】:

好发现!在我看来,这就像argparse 中的错误/设计决策。如果您说要为global-argument 提供值sub,应该是什么逻辑-您如何告诉argparse 它是全局位置参数而不是有效的子解析器命令名称?我希望他们支持--,但这也不起作用。最好在 Python 错误跟踪器中询问。如果需要,至少应该记录在案(不是)。 @blami,一般来说,主要的解析器参数都应该在创建subparsers之前定义。您可以在之后添加optional,但不能添加另一个positional。有关详细信息,请参阅我的答案。 @hpaulj 谢谢!这很有用! 【参考方案1】:

parsersubparserspositional 参数,global-argument 也是。 positionals 按照定义的顺序进行解析。但是由于解析是在遇到时传递给子解析器,而不是传回主解析器,所以在任何情况下都可以处理“全局参数”。

optional 可以在之后为 parser 定义,但这是因为 optionals 的处理顺序是为了让用户提供它们。

parsersubparsers 只是positional 的一种特殊类型,它将解析任务传递给另一个解析器。 sub_parser 在被调用时处理剩余的字符串,并返回一个namespace,它被合并到主namespace 中。 parser 不会继续解析。

所以主解析器的参数都应该首先定义,并首先在命令行中使用。 subparser(s) 和参数在此之后定义和使用。

最初subparsers 不是可选的,这对于positionals 来说是正常的(没有特殊的nargs)。但是,作为更改“必需”参数的测试和标记方式的意外副作用,subparsers 默认情况下变为不需要的。一段时间以来,我们一直在处理由此带来的后果。

我投票最多的答案与此有关; Argparse with required subparser

包含dest 也是一个好主意,既可以更好地识别使用了哪个子解析器,又可以防止错误消息中出现问题。

subparsers = parser.add_subparsers(dest='cmd')

【讨论】:

首先很抱歉以这种方式与您联系。我很佩服你的麻木技能。我正在努力学习它。有什么好的教程,你知道的课程吗? @wwnde,我没看过教程。通常我只是鼓励人们阅读基本文档,例如numpy.org/doc/stable/user/absolute_beginners.html。很难将我从 2006 年的原著 web.mit.edu/dvp/Public/numpybook.pdf 中学到的东西与我从使用和 SO 中学到的东西区分开来。 不错,我一定会按照建议查看文档。非常感谢

以上是关于带有可选子命令的 argparse 未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

带有可选子路径的 Laravel 路由

带有自动布局的 uiscrollview 的动态内容未按预期工作

带有导航器的颤振模态底部工作表未按预期弹出

带有 Kotlin 的 Spring Boot - @Value 注释未按预期工作

带有分页的可扩展嵌套 Angular 材料数据表未按预期工作?

带有一个 goto 标签的 C 代码未按预期工作