在Python 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在参数给定时并不会返回True
、False
或None
。有没有简单的方法可以添加这个功能?当然,之后我可以执行类似这样的操作:
args.value = values[args.value]
这实际上就是我现在在做的,但这和默认值不太兼容(我需要检查值是否已经是None,或者把默认值设置为"switch"
)。而且因为我多次使用这个,所以每次都得这么做。
3 个回答
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在程序中使用这些数据。这个过程可能会涉及到很多步骤,比如连接到数据库、查询数据、处理数据等等。
在这个过程中,可能会遇到一些问题,比如数据格式不对、连接失败等等。这些问题可能会导致程序出错,或者获取不到我们想要的数据。
为了避免这些问题,我们可以采取一些措施,比如检查数据的格式、确保连接正常、使用错误处理机制等等。这样可以提高程序的稳定性和可靠性。
总之,处理数据是编程中一个重要的部分,我们需要认真对待,确保每一步都能顺利进行。
values = { "on": True, "off": False, "switch": None }
parser.add_argument("-v", "--value", choices=values.keys())
value = values.get(args.value)
我无法对oekopez的回答进行评论,但这个改动会让这个类可以用于任何传递给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)
最简单的改动是使用
args.value = values.get(args.values)
这样的话,对于字典中没有的任何条目,你会得到None(比如默认值)。
另一种选择是错误地使用argparse的type关键字:
values = { "on": True, "off": False, "switch": None }
def convertvalues(value):
return values.get(value)
parser.add_argument('-v','--value',type=convertvalues)
这种“类型”方法会破坏上面提到的choices的使用,因为choices是在转换之后应用的。为了保留你使用choices的方式,可以这样做:
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'不在choices中,所以你会得到预期的错误信息。
使用“action”并结合从argparse.Action派生的类,而不是使用type,应该能更聪明地解决这个问题,具体可以参考文档:
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)
当然,这并不是完美的,更好的解决方案是重写Action的init方法,以获取字典,并省略硬编码的value_dict。