更改 argparse 用法消息参数顺序

Change argparse usage message argument order

我在 python3 中使用 argparse。在我的脚本中,我有一些子解析器、一个位置参数和一些可选参数。我有一个可选参数来传递任意数量的文件路径,它使用 nargs='*'。我的脚本的用法消息如下所示:

usage: myprog.py subparser1 [-h] [--dir DIR] 
                            [--files [FILES [FILES ...]]]
                            positional_arg

但是,如果您真的按照此用法消息的建议将 positional_arg 放在 --files 标志之后,我认为解析器最终会将其作为文件路径使用(因为 nargs='*'), 然后抛出错误,因为它没有找到所需的 positional_arg.

我认为使用消息的打印方式具有误导性。由于我有多个子解析器,我想找到一种方法来更改所有使用消息(无需使用 usage= 参数手动键入它们),以便首先显示位置参数,希望能消除混淆.

所以我的主要问题是如何更改参数在 argparse 消息的使用部分中的排序方式?

编辑以解决一种对我不起作用的可能解决方案。

我不想添加 --files 标志作为 nargs='*' 的位置参数。首先,因为这使得它现在显示在帮助消息的 "positional arguments" 部分而不是 "optional arguments" 部分以及我的其余可选参数,所以它看起来像是必需的,即使你可以给它传递 0 个参数。

其次,因为如果我想要另一个标志,除了 --files(例如 --folders)之外还可以接受任意数量的参数,并且如果我将它们都设为位置参数,我'd 运行 遇到同样的问题,第一个问题会一直消耗参数直到结束。如果我做了一个位置和一个可选,那么误导性的使用信息仍然是一个问题。

因为argparse 没有对选项在命令行中的使用位置施加任何限制,所以选项接受任意数量的参数实际上没有意义。另一方面,位置参数 do 具有强制顺序。我会做类似

的事情
add_argument("positional_arg")
add_argument("files", nargs='*', help="Optional, one or more files")

相反,将 --files 选项转换为纯可选位置参数的列表。然后,无论是在帮助消息中还是在实际使用中,都不会混淆哪些参数是文件列表的一部分。

这里有几个问题 - 如何解析参数以及如何格式化用法。

几个快速修复:

使用 -- 标记可选列表的结尾和位置的开始。

另一种可能性是将您的 positional 变成 optional。也就是说,如果需要,给它一个简单的标志和 required 参数。然后它可以放在子解析器输入的任何地方。


https://whosebug.com/a/26986546/901925 解决了 * 可选后面的位置问题。它提出了同样的快速建议。它还显示了如何更改帮助格式化程序以不将位置移动到使用的末尾。但它没有解决 multi-line 用例。

在最近的 SO 问题中也讨论了使用顺序, https://whosebug.com/a/29619171/901925


如果您不喜欢默认的参数分组(位置参数和可选参数),您可以使用 argument_groups 不同的标题和描述。像'?'这样的nargs和“*”以及 'required' 参数,'optionals' 和 'positionals' 等名称可能会造成混淆。我正在尝试将 'flagged' 用于 'optionals',希望它不那么令人困惑。