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

grouping an unknown number of arguments with argparse

我正在为需要能够接受一组或多组选项的命令行程序设计用户界面。每个组都是一样的,但是需要连在一起,像这样:

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

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

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

,实际上会好得多
./myprogram.py --group1 firstname:name1 secondname:name2 firstpath:pathA secondpath:pathB

但我知道 argparse 不支持 dict 类型,任何允许它的 hack 都会更不友好。

您可以将 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']])

从这里,您可以根据需要解析 key-value 对。


另一种选择是使用自定义操作来进行解析——这是一个简单的方法,它接受 --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()

这没有检查(所以如果 key:value 的格式不正确,用户可能会觉得 TypeErrors 很有趣)并且如果你想将它限制为指定的键,你需要也构建它......但是这些细节应该很容易添加。您还可以要求他们使用 self.nargs = 4 in DictAction.__init__.

提供 4 个值