使用argparse对未知数量的参数进行分组

时间:2016-01-21 17:39:38

标签: python argparse

我正在为命令行程序设计用户界面,该程序需要能够接受一组或多组选项。每个组都是相同的,但需要链接在一起,如下所示:

./myprogram.py --group1 name1,name2,pathA,pathB --group2 name3,name4,pathC,pathD

对于用户来说,这似乎非常笨拙。我考虑过使用INI - 样式configparser设置,但它也很笨重,因为除此之外我还有很多其他参数通常都有默认值,然后我失去了所有的功能用于处理需求的argparse模块,检查文件是否存在等等。

有没有人对如何最好地构建我的ArgumentParser有任何想法,以便我可以让用户一起为给定的组提供四个必需的输入?我没有以逗号分隔列表结婚,这只是一个例子。如果他们可以输入某种键值对,实际上要好得多,例如

./myprogram.py --group1 firstname:name1 secondname:name2 firstpath:pathA secondpath:pathB

但我知道argparse不支持dict类型,任何允许它的黑客都会更不方便用户。

1 个答案:

答案 0 :(得分:3)

您可以将nargs=4'append'操作一起使用:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--group', nargs=4, action='append')

print parser.parse_args()

它被称为:

$ python ~/sandbox/test.py --group 1 2 3 4 --group 1 2 3 4
Namespace(group=[['1', '2', '3', '4'], ['1', '2', '3', '4']])

从这里开始,您可以根据需要解析键值对。

另一种选择是使用自定义操作来进行解析 - 这是一个接受--group key:value key2:value2 ... --group ...

形式的参数的简单方法
import argparse

class DictAction(argparse.Action):
    def __init__(self, *args, **kwargs):
        super(DictAction, self).__init__(*args, **kwargs)
        self.nargs = '*'

    def __call__(self, parser, namespace, values, option_string=None):
        # The default value is often set to `None` rather than an empty list.
        current_arg_vals = getattr(namespace, self.dest, []) or []
        setattr(namespace, self.dest, current_arg_vals)
        arg_vals = getattr(namespace, self.dest)
        arg_vals.append(dict(v.split(':') for v in values))

parser = argparse.ArgumentParser()
parser.add_argument('--group', action=DictAction)

print parser.parse_args()

这没有检查(如果TypeError格式不正确,用户可能会变得有趣key:value)如果你想将它限制为指定的密钥,你需要构建它同样......但这些细节应该很容易添加。您还可以要求他们使用self.nargs = 4中的DictAction.__init__提供4个值。