将可选列表传递给argparse

时间:2015-03-13 17:47:56

标签: python argparse

是否有更优雅的方式将可选的整数列表传递给argparse而不是pass a delimited string and parse it later?我也有一个位置论证。

parser.add_argument('--ids', type=int, nargs='+')
parser.add_argument('cmd')

不起作用,因为argparse试图抓住cmd并抱怨它不是一个整数。

理想情况下,我想用

之一执行
program.py --ids 6,32,12 refresh
program.py --ids 6 32 12 refresh

或类似的东西,但也能够

program.py refresh

2 个答案:

答案 0 :(得分:2)

--是一种方便的方式,可以说'位置论证从这里开始'。

使用解析器,这些工作:

program.py refresh   # sets ids=None
program.py refresh --ids 1 2 3
program.py --ids 1 2 3 -- refresh

如果您不喜欢--ids,可以将None参数设为默认值(例如[])。

program.py refesh --ids 1,2,3的任何问题都归因于shell如何拆分命令行。查看sys.argv列表。

出现program.py --ids 1 2 3 refresh的问题,因为在处理--ids时,解析器会尝试使用后面显然不是标志的所有字符串(例如使用' - ')。它不使用'int'类型来测试使用哪些以及要离开哪些。

现在,如果ids处于位置,它将处理1 2 3 refresh

parser.add_argument('ids',type=int,nargs='+')
parser.add_argument('cmd')
parser.parse_args('1 2 3 refresh'.split())

但那是因为解析器使用不同的策略将字符串分配给多个位置参数。它使用re匹配器,看起来像A+A


Kevin的type方法可能更好地通过一个简单的函数实现:

def mytype(astring):
    ll = astring.split(',')
    return [int(l) for l in ll]
parser.add_argument('--ids', type=mytype)

可以推广处理像“1 2 3”这样的引用字符串。 type可以是任何带字符串的函数,并返回所需的值,如果无法进行转换,则会引发错误。

答案 1 :(得分:2)

如果你只想解析--ids 1,2,3形式的参数(没有空格),你可以使用这样的东西:

def convert(argument):
    return map(int, argument.split(','))  # 3.x: consider wrapping in list()

parser.add_argument('--ids', type=convert)

这不会处理由空格分隔的参数,尽管您可以使用更智能的convert()函数来缓解这种情况。然而,您需要引用它们,否则shell会将它们作为单独的参数传递。