使用Python argparse的字典

时间:2014-03-25 13:10:47

标签: python dictionary argparse

我有一个字典,它将人类可读的值映射到三个不同的Python特定值。 argparse Python模块如何使用此字典来获取特定值,同时用户可以在键之间进行选择。

目前我有这个:

def parse(a):
    values = { "on": True, "off": False, "switch": None }
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--value", choices=values, default=None)
    args = parser.parse_args(a)
    print("{}: {}".format(type(args.value), args.value))

>>> parse(['-v', 'on'])
<type 'str'>: on
>>> parse(['-v', 'off'])
<type 'str'>: off
>>> parse(['-v', 'switch'])
<type 'str'>: switch
>>> parse([])
<type 'NoneType'>: None

问题是,如果给出参数,argparse不会返回TrueFalseNone。有没有简单的方法来添加此功能?当然,我之后可以执行这样的事情:

args.value = values[args.value]

这实际上是我目前正在做的事情,但这对默认值不起作用(我必须检查该值是否为None或将默认值设置为"switch")。而且,由于我多次使用它,我每次都必须这样做。

3 个答案:

答案 0 :(得分:3)

最小的改变是使用

args.value = values.get(args.values)

因此,对于不在dict中的任何条目(例如默认值),您将获得None。

另一个选择是滥用argparse的类型关键字:

values = { "on": True, "off": False, "switch": None }
def convertvalues(value):
    return values.get(value)
parser.add_argument('-v','--value',type=convertvalues)

“类型”方法会破坏上面使用的选项,因为选择是在转换后应用的。保留您使用选择的一种可能性是:

def convertvalues(value):
     return values.get(value,value)
parser.add_argument('-v','--value',type=convertvalues,
                                   choices=[True,False,None],
                                   default=None)

在这种情况下,如果使用'on','off','switch'和None,convertvalues将返回正确的值,如果给出了其他内容,则返回给定的值(例如'bla')。由于'bla'不在选择中,因此您会收到预期的错误消息。

对于从argparse.Action而不是类型派生的类,使用“action”应该以聪明的方式完成工作,如docs中所示:

class DictAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        value_dict = { "on": True, "off": False, "switch": None }
        setattr(namespace, self.dest, value_dict.get(values))
parser.add_argument('-v','--value',action=DictAction,
                                   choices=['on','off','switch'],
                                   default=None)

当然这并不完美,更好的解决方案会覆盖Acion init 来获取字典并省略硬编码的value_dict。

答案 1 :(得分:0)

values = { "on": True, "off": False, "switch": None }
parser.add_argument("-v", "--value", choices=values.keys())
value = values.get(args.value)

答案 2 :(得分:0)

我无法对oekopez&#39;发表评论。回答, 但是这个改变将使该类可用于传递给add_argument动作的任何字典。

class DictAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, self.choices.get(values, self.default))

value_dict = { "on": True, "off": False, "switch": None }
parser.add_argument('-v','--value',action=DictAction,
                               choices=value_dict,
                               default=None)