argparse 有没有办法让第一个位置参数不仅是无破折号的,而且是多个可能的用户输入值之一?

Is there a way with argparse to allow the first positional arguments to not only be dashless, but also one of multiple possible user-inputted values?

我可以使用 sys.argv 实现我需要的功能,但无法找到允许此功能的 argparse 等价物。
目前使用 sys.argv 我可以方便地允许程序以这种方式 运行 命令:

python program.py ls
python program.py del input
python program.py arg
python program.py input input2  

ls--不变的关键字参数--它进入字典并列出它的键。
del input--del 是一个关键字,指定用户的 input 是应该从字典中删除的关键字。
arg--可以是字典中众多键中的任何一个。
input input2--是一个全新的键和值被添加到字典中。

提供字典相关信息只是为了说明参数的作用。

除了没有破折号之外,还允许多个参数位于第一个位置。此外,两个第一位置参数(inputdel)可以为用户提供一个全新的、未指定的第二位置参数。

乍一看,这看起来像是一个子解析器案例,其中包含 'ls'、'del' 等命令。我只是勾勒出一个示例,其中子解析器在 class

中定义

但这些输入使情况复杂化:

python program.py <key>
program.py <key value>

不清楚 key 值是来自程序员定义的字典,还是用户的任意值。

可以将程序员定义的字典中的键添加为子解析器,如我的示例所示。

但是任意 'key value' 条目需要不同的定义。有很多问题是人们要求输入某种 key:valuekey=value 对。 argparse 没有很好地处理这个问题。对于程序员想要完全控制输入的情况更好。

也许最简单的argparse方法是

parser.add_argument('cmd')    # simple required 1 term positional
parser.add_argument('value', nargs='?')   # optional term

然后你自己测试 args.cmdargs.value 字符串。这对评估 sys.argv[1]sys.argv[2:].

没有太大帮助

cmdchoices 的行为很像子解析器 cmd,将值限制为一组已定义的字符串。

optparse 处理标记的 (--) 参数,并将所有位置作为列表传回。 argparse 试图通过提供 nargs 参数和定义某些 positionals 的能力来增强这一点。但它仍然更好地处理大量带标记的参数。 positionals 的内容测试是有限的。

总之,移植到 argparse 可能不会给您带来任何好处。你是在违背它的标准而不是与它们一起工作。


脚本比较 argparse 和 sys.argv 解析

import sys

key = None
if sys.argv[1:]:
    key = sys.argv[1]
value = sys.argv[2:]

print(key, value)

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('key')
parser.add_argument('value', nargs='*')
args = parser.parse_args()
print(args)

在这里,我将除第一个字符串之外的所有字符串放入列表中。采用 '?'可选择只接受一个字符串。

样本运行:

1111:~/mypy$ python stack46631607.py 
(None, [])
usage: stack46631607.py [-h] key [value [value ...]]
stack46631607.py: error: too few arguments

1111:~/mypy$ python stack46631607.py ls
('ls', [])
Namespace(key='ls', value=[])

1112:~/mypy$ python stack46631607.py del input
('del', ['input'])
Namespace(key='del', value=['input'])

1112:~/mypy$ python stack46631607.py key 1 2 3
('key', ['1', '2', '3'])
Namespace(key='key', value=['1', '2', '3'])

1112:~/mypy$ python stack46631607.py -h
('-h', [])

usage: stack46631607.py [-h] key [value [value ...]]

positional arguments:
  key
  value

optional arguments:
  -h, --help  show this help message and exit

argparse 添加错误检查(即缺少第一个字符串)和帮助。

决定如何处理 args.key 值由您决定,就像决定它是否 requires/accepts 一个 value 列表一样。据我所知,您对 ls 的处理与 'arg' 相同,而 'del' 类似于 'input'.