带有可选子命令的 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】:
致parser
。 subparsers
是 positional
参数,global-argument
也是。 positionals
按照定义的顺序进行解析。但是由于解析是在遇到时传递给子解析器,而不是传回主解析器,所以在任何情况下都可以处理“全局参数”。
optional
可以在之后为 parser
定义,但这是因为 optionals
的处理顺序是为了让用户提供它们。
致parser
。 subparsers
只是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 未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
带有自动布局的 uiscrollview 的动态内容未按预期工作
带有 Kotlin 的 Spring Boot - @Value 注释未按预期工作