问题描述
我正在为命令行程序设计用户界面,该程序需要能够接受一个或多个选项组.每个组都是相同的,但是需要链接在一起,就像这样:
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
类型,任何允许它的黑客都将变得不那么用户友好.
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
格式不正确,用户可能会得到有趣的TypeError
),并且如果您希望将其限制为指定的键,则还需要内置该键. ..但这些细节应该很容易添加.您还可能要求使用DictAction.__init__
中的self.nargs = 4
提供四个值.
This has no checking (so the user could get funny TypeError
s 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将未知数量的参数分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!