【问题标题】:Python argparse with choices and nargs=2带有选择和 nargs=2 的 Python argparse
【发布时间】:2018-06-29 03:26:43
【问题描述】:

我正在尝试创建一个带有两个参数的选项。第一个参数应该通过选择进行验证,但第二个参数是用户提供的任意值。例如。

> app -h
usage: app [--option {count,label} arg]

正确用法示例:

> app --option count 1
> app --option count 912
> app --option label userfoo

我试过这样设置:

parser.add_argument('--option', choices=['count','label'], nargs=2)

这不起作用,因为它尝试使用选项验证两个参数。帮助字符串显示:

usage: app [--option {count,label} {count,label}]

有几种方法可以手动完成:

  • 删除选择字段并手动验证代码中的第一个参数。
  • 将其分离为--option count --value 3,但这很尴尬,因为选项需要--value,但如果没有它则无效。它实际上是一个具有两个值的单一选项
  • 使 --option 有一个复合值,例如--option count=3 然后解析该值

我想要的部分是让自动生成的帮助字符串显示第一个参数的选择。我还希望 argparse 尽可能使用最少的自定义代码来检测和报告错误。原因是我们有一个非常复杂的 CLI,这有助于保持一致性。

有没有办法用 argparse 做到这一点?

【问题讨论】:

  • 这个 SO 问题很好地讨论了如何做到这一点,以及为什么单个选项有多个值可能不好:stackoverflow.com/questions/4109436/…
  • 您可以编写一个自定义的type 函数和/或Action 类来处理这个问题。或者您可以在解析后进行值测试。但正如您发现的那样,argparse 通常对所有 nargs 值应用相同的测试。

标签: python argparse


【解决方案1】:

parser._get_values 确实如此,当nargs 是数字时:

        value = [self._get_value(action, v) for v in arg_strings]
        for v in value:
            self._check_value(action, v)

_get_value 应用type 函数,而_check_value 测试choices。在此之后,values 列表将传递给 store 操作。

所以正常处理对每个字符串应用相同的typechoices 测试。

我可以想象编写一个type 函数,它接受列表中的数字和字符串。但它无法区分第一个参数和第二个参数。自定义 Action 将同时看到两者,并且可以进行进一步测试。

但通常在解析后进行自己的值测试会更简单。 parser 不必做所有事情。它的主要功能是弄清楚用户想要什么。检查值和引发标准化错误是解析的一个很好的部分,但不是其主要目的。

还要考虑如何为预期输入指定用法/帮助。

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 2020-10-26
    • 2020-01-04
    • 2023-01-22
    • 2022-08-19
    • 2014-10-11
    • 2022-11-19
    • 2016-11-01
    • 2017-08-20
    相关资源
    最近更新 更多