我想使用argparse的{choices}参数,但允许用户从选项中输入任意数量的项目。例如,如果选择是[1,2,3],我希望以下内容有效:
--arg 1
--arg 1,2
--arg 1,3
等
然而,当使用nargs =" +"时,选择似乎不接受以逗号分隔的输入。有没有办法解决?我仍然希望强制传入的选项在我定义的选项集中,以便对奇怪的输入进行错误检查。
答案 0 :(得分:2)
我同意 - 你会认为API现在允许有人这样做吗?
嗯,无论如何,我一直使用的解决方法如下:
p = argparse.ArgumentParser(description="Why doesn't argparse support list of args?")
parser.add_argument('--arg', type=str)
arg_list = parser.parse_args().args.split(",")
# if you wanted integers:
arg_list = [int(x) for x in arg_list]
AKA:接受一个字符串并自行处理。
答案 1 :(得分:1)
这个单行代码为您提供了所有可能的子集。
from itertools import combinations, chain
allsubsets = lambda n: list(chain(*[combinations(range(n), ni) for ni in range(n+1)]))
答案 2 :(得分:0)
以下是我实现这一目标的方法:
import argparse
arg=argparse.ArgumentParser()
arg.add_argument( "--lista", nargs="*", type=int, default=[1, 2, 3], )
args = arg.parse_args()
print("lista: {0}" .format(args.lista))
答案 3 :(得分:0)
import argparse, sys
print(sys.argv)
parser = argparse.ArgumentParser()
parser.add_argument('--arg', nargs='+', choices=[1,2,3], type=int)
args = parser.parse_args()
print(args)
一些运行
1455:~/mypy$ python stack49824248.py --arg 1
['stack49824248.py', '--arg', '1']
Namespace(arg=[1])
1455:~/mypy$ python stack49824248.py --arg 1 3 2 1
['stack49824248.py', '--arg', '1', '3', '2', '1']
Namespace(arg=[1, 3, 2, 1])
1456:~/mypy$ python stack49824248.py --arg 1,2
['stack49824248.py', '--arg', '1,2']
usage: stack49824248.py [-h] [--arg {1,2,3} [{1,2,3} ...]]
stack49824248.py: error: argument --arg: invalid int value: '1,2'
shell与解释器一起拆分空格上的输入,并在sys.argv
中提供字符串列表。这是parser
处理的内容。
使用+
,--arg
操作接受字符串列表(到结束标记或下一个标记)。每个字符串都通过type
函数传递,结果与choices
(如果提供)进行比较。在这种情况下,type
为int
,因此选项也可以是整数。如果没有type
,则choices
必须为['1','2','3']
。
如果我将参数更改为:
parser.add_argument('--arg', nargs='+', choices=['1','2','3','1,2','2,3'])
它会接受逗号的一些字符串:
1456:~/mypy$ python stack49824248.py --arg 1
['stack49824248.py', '--arg', '1']
Namespace(arg=['1'])
1505:~/mypy$ python stack49824248.py --arg 1,2
['stack49824248.py', '--arg', '1,2']
Namespace(arg=['1,2'])
1505:~/mypy$ python stack49824248.py --arg 1,2,3
['stack49824248.py', '--arg', '1,2,3']
usage: stack49824248.py [-h] [--arg {1,2,3,1,2,2,3} [{1,2,3,1,2,2,3} ...]]
stack49824248.py: error: argument --arg: invalid choice: '1,2,3' (choose from '1', '2', '3', '1,2', '2,3')
我没有包含' 1,2,3'选择,所以它拒绝了。另请注意,我删除了int
type
,因为int('1,2')
将失败。
因此,如果您需要接受' 1,2,3',请在解析后(或可能作为自定义Action
类)进行自己的拆分和选择测试。
In [16]: [(int(x) in [1,2,3]) for x in '1,2,3'.split(',')]
Out[16]: [True, True, True]
In [17]: [(int(x) in [1,2,3]) for x in '1,2,4'.split(',')]
Out[17]: [True, True, False]
In [18]: [(int(x) in [1,2,3]) for x in '1,a,4'.split(',')]
....
ValueError: invalid literal for int() with base 10: 'a'