argparse:如何允许带有 nargs="*" 和选项的空列表

Posted

技术标签:

【中文标题】argparse:如何允许带有 nargs="*" 和选项的空列表【英文标题】:argparse: How to allow empty list with nargs="*" and choices 【发布时间】:2020-01-04 10:48:04 【问题描述】:

argparse 中,如何创建一个可选的位置命令行选项,该选项接受多个参数,这些参数都需要成为选项列表的一部分?

在下面的示例中,我想允许列表 ['a', 'b', 'c'] 的任何子集——即 ['a']['a', 'c']、...以及至关重要的空列表 []。我期待以下实现这一点,但如果参数被省略,它会失败。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('letters', nargs='*', choices=['a', 'b', 'c'])
args = parser.parse_args()

error: argument letters: invalid choice: [] (choose from 'a', 'b', 'c')

更新:我发现choices=['a', 'b', 'c', []] 似乎可以完成这项工作。这让我感到矛盾,因为它表明argparse 检查[] in choices,这意味着['a'] 也应该在choices 中(而不是'a')。

【问题讨论】:

任何支持in 运算符的对象都可以传递给选择。奇怪的是,您需要使用空列表而不是空字符串或 None 来完成空选择。 同意。 None'' 是我收到错误时尝试的第一件事。虽然我希望检查与all([_ in choices for _ in args]) 一致,但这不应该要求在选择中明确包含。 * 位置满足 [] 空输入列表。但它不应该通过选择测试。我将不得不查看代码以了解发生了什么。它将在 _get_values_get_value 方法中。我很惊讶我不记得看到有关此的错误/问题。 一个相关问题刚刚得到更多关注:bugs.python.org/issue9625,其他链接bugs.python.org/issue27227,bugs.python.org/issue16878,***.com/questions/41750896/… 是否应该允许重复?我的意思是 parser.parse_args(['a', 'a']) 不会引发错误。 【参考方案1】:

我觉得这个问题(要求空列表默认​​)基本上是more general question的特例,要求其他默认。

typed_argparse 的基础上调整my other answer 来适应这个具体案例:

import argparse
from typed_argparse import Choices

parser = argparse.ArgumentParser()
parser.add_argument(
    "letters", 
    choices=Choices("a", "b", "c"),  # Wrap the choices in Choices
    default=[],  # Empty list possible as default
    nargs="*",
)

Choices 的实现非常简单,如果您喜欢可复制/可粘贴的内容。

【讨论】:

以上是关于argparse:如何允许带有 nargs="*" 和选项的空列表的主要内容,如果未能解决你的问题,请参考以下文章

具有 nargs 行为的 Python argparse 不正确

argparse 错误: 'nargs 必须是 %r 才能提供 const' % OPTIONAL)

如何使 argparse 将所有参数视为位置?

argparse模块见解

用 argparse 杀死解释器

argparse之add_argument() 方法