允许argparse nargs =" +"接受逗号分隔的输入和选择

时间:2018-04-13 19:56:32

标签: python argparse

我想使用argparse的{choices}参数,但允许用户从选项中输入任意数量的项目。例如,如果选择是[1,2,3],我希望以下内容有效:

--arg 1
--arg 1,2
--arg 1,3

然而,当使用nargs =" +"时,选择似乎不接受以逗号分隔的输入。有没有办法解决?我仍然希望强制传入的选项在我定义的选项集中,以便对奇怪的输入进行错误检查。

4 个答案:

答案 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(如果提供)进行比较。在这种情况下,typeint,因此选项也可以是整数。如果没有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'