使用 argparse 对未知数量的参数进行分组 [英] grouping an unknown number of arguments with argparse

查看:25
本文介绍了使用 argparse 对未知数量的参数进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am designing the user interface for a command line program that needs to be able to accept one or more groups of options. Each group is the same, but needs to be linked together, like so:

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

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

This seems very clunky for a user to deal with. I have considered using a INI-style configparser setup, but it is also clunky, because I have a lot of other arguments besides this that generally have default values, and then I lose all of the power of the argparse module for handling requirements, checking if files exist, etc.

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

Does anyone have any ideas on how I could best structure my ArgumentParser so that I can get a user to provide the four required inputs for a given group, together? I am not married to the comma separated list, that was just an example. It would actually be far better if they could enter some sort of key-value pair, such as

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

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

But I know that argparse does not support the dict type, and any hack to allow it would be even less user-friendly.

推荐答案

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

You can use nargs=4 with an 'append' action:

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']])

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

From here, you can parse the key-value pairs if you'd like.

另一种选择是使用自定义操作进行解析——这是一个简单的操作,它接受形式为 --group key:value key2:value2 ... --group ...

Another option is to use a custom action to do the parsing -- Here's a simple one which accepts arguments of the form --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)并且如果你想将其限制为指定的键,您还需要构建它......但这些细节应该很容易添加.您还可以要求他们使用 DictAction.__init__ 中的 self.nargs = 4 提供 4 个值.

This has no checking (so the user could get funny TypeErrors if the key:value are not formatted properly) and if you want to restrict it to specified keys, you'll need to build that in as well... but those details should be easy enough to add. You could also require that they provide 4 values using self.nargs = 4 in DictAction.__init__.

这篇关于使用 argparse 对未知数量的参数进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆