[英]argparse: how to configure multiple choice, multiple value, optional argument?
I'm trying to set up an argument that accepts one or more values from a given list of choices, but is not obligatory.我正在尝试设置一个参数,该参数接受给定选项列表中的一个或多个值,但不是强制性的。 I'm trying this (with a couple of variants that also don't work as expected):
我正在尝试这个(有几个变体也不能按预期工作):
parser.add_argument("FLAGS", nargs='*', choices=["X","Y","Z","ALL"])
I expect to get a list of values from the list of choices, or an empty list if nothing was given (that, I think, should be enforced by nargs='*'
).我希望从选择列表中获得一个值列表,或者如果没有给出任何内容,则获得一个空列表(我认为应该由
nargs='*'
强制执行)。 But regardless of whether I add default=""
or not, when I don't pass any argument it fails with:但无论我是否添加
default=""
,当我不传递任何参数时,它都会失败:
error: argument FLAGS: invalid choice: []
How to achieve what I need?如何实现我所需要的?
This probably doesn't fit your needs, but you can do it easily with an option like --flags
.这可能不符合您的需求,但您可以使用
--flags
类的选项轻松完成。
parser.add_argument(
"--flags",
nargs='*',
default=[], # Instead of "None"
choices=["X", "Y", "Z", "ALL"])
args = parser.parse_args()
print(args)
$ tmp.py
Namespace(flags=[])
$ tmp.py --flags
Namespace(flags=[])
$ tmp.py --flags X
Namespace(flags=['X'])
$ tmp.py --flags X Z
Namespace(flags=['X', 'Z'])
$ tmp.py --flags foobar
usage: tmp.py [-h] [--flags [{X,Y,Z,ALL} ...]]
tmp.py: error: argument --flags: invalid choice: 'foobar' (choose from 'X', 'Y', 'Z', 'ALL')
$ tmp.py --help
usage: tmp.py [-h] [--flags [{X,Y,Z,ALL} ...]]
optional arguments:
-h, --help show this help message and exit
--flags [{X,Y,Z,ALL} ...]
A positional '*' gets some special handling.位置“*”得到一些特殊处理。 Its
nargs
is satisfied with an empty list (nothing).它的
nargs
对空列表(无)感到满意。 It's always handled.它总是被处理。 What does it mean to check an empty list of strings against the
choices
?根据
choices
检查一个空的字符串列表是什么意思?
So the get_values()
method does:所以
get_values()
方法会:
# when nargs='*' on a positional, if there were no command-line
# args, use the default if it is anything other than None
elif (not arg_strings and action.nargs == ZERO_OR_MORE and
not action.option_strings):
if action.default is not None:
value = action.default
else:
value = arg_strings
self._check_value(action, value)
where _check_value
tests if value
is in the choices
.其中
_check_value
测试value
是否在choices
中。
Such a positional is best used with a valid default
.这种位置最好与有效的
default
一起使用。
In [729]: p=argparse.ArgumentParser()
In [730]: a=p.add_argument("FLAGS", nargs='*', choices=["X","Y","Z","ALL"])
In [731]: p.parse_args([])
usage: ipython3 [-h] [{X,Y,Z,ALL} [{X,Y,Z,ALL} ...]]
ipython3: error: argument FLAGS: invalid choice: [] (choose from 'X', 'Y', 'Z', 'ALL')
...
Testing an empty list against choices
fails:针对
choices
测试空列表失败:
In [732]: a.choices
Out[732]: ['X', 'Y', 'Z', 'ALL']
In [733]: [] in a.choices
Out[733]: False
In [734]: 'X' in a.choices
Out[734]: True
If we set a valid default:如果我们设置一个有效的默认值:
In [735]: a.default='X'
In [736]: p.parse_args([])
Out[736]: Namespace(FLAGS='X')
This behavior is part of what allows us to use such a positional in a mutually_exclusive_group
.这种行为是允许我们在
mutually_exclusive_group
组中使用这种位置的一部分。
If you don't want to specify a valid default, then changing this to a flagged argument avoids the problem.如果您不想指定有效的默认值,则将其更改为标记参数可以避免该问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.