使用 argparse 和 python 接受字典作为参数 [英] Accepting a dictionary as an argument with argparse and python

查看:55
本文介绍了使用 argparse 和 python 接受字典作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 argparse 接受 type=dict 的参数,但无论输入如何,它都会给出无效 dict 值的错误.

#!/usr/bin/env python导入参数解析MYDICT = {'key': 'value'}解析器 = argparse.ArgumentParser()parser.add_argument("-m", "--mydict", action="store",必需=假,类型=字典,默认=MYDICT)args = parser.parse_args()打印 args.mydict

当我尝试将字典传递给脚本时会发生这种情况

./argp.py -m "{'key1': 'value1'}"用法:argp.py [-h] [-m MYDICT]argp.py:错误:参数 -m/--mydict:无效的字典值:{'key1':'value1'}"

查看文档我认为这是可能的.

http://docs.python.org/dev/library/argparse.html>

任何支持 in 操作符的对象都可以作为choices 值传递,所以字典对象、集合对象、自定义容器等都被支持."

解决方案

我不认为可以在命令行中将字典作为参数传递,因为不存在从字符串到字典的转换函数(EDIT:黑客可能会产生类似的行为,见下文).你本质上告诉python要做的是:

dict("{'key1': 'value1'}")

如果您在 python 控制台中尝试,则不起作用.

什么短语:

任何支持 in 操作符的对象都可以作为choices 值传递,所以字典对象、集合对象、自定义容器等都被支持."

指的是可以通过 add_argument 函数传递的 choices 参数 - 而不是 type 参数.

您最好的选择是将您的参数作为字符串接受,然后使用 json python 的能力:

parser.add_argument('-m', '--my-dict', type=str)args = parser.parse_args()导入jsonmy_dictionary = json.loads(args.my_dict)

然后您可以以字符串的形式传递字典.您可以在 python 控制台中亲自尝试 json 编码器/解码器,看看它是如何工作的:

>>>json.loads('{value1":key1"}'){u'value1': u'key1'}

编辑:hpaulj 向我指出你可以破解"type 参数通过传递 json.loads 允许您传递类似于字典的 JSON.

导入jsonparser.add_argument('-d', '--my-dict', type=json.loads)args = parse.parse_args()mydict = args.my_dict # 会返回一个字典

注意:您传递的输入格式与 python 字典不同,但对于您的用例来说可能足够相似.

这个工作的原因实际上很有趣,因为在内部 argparse 只会使用参数值作为一个函数来转换参数.即如果 type=int 那么它将使用 int(arg) 或者如果 type=json.loads 那么 json.loads(arg)

这也意味着您可以传递任何将单个参数作为参数输入的函数,并在需要时执行自定义转换:)

I'm trying to accept an argument of type=dict with argparse but no matter the input it gives an error of invalid dict value.

#!/usr/bin/env python

import argparse

MYDICT = {'key': 'value'}

parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mydict", action="store",
                    required=False, type=dict,
                    default=MYDICT)

args = parser.parse_args()

print args.mydict

This is what happens when I try and pass a dictionary to the script

./argp.py -m "{'key1': 'value1'}"
usage: argp.py [-h] [-m MYDICT]
argp.py: error: argument -m/--mydict: invalid dict value: "{'key1': 'value1'}"

Looking at the documents I would think that this would be possible.

http://docs.python.org/dev/library/argparse.html

"Any object that supports the in operator can be passed as the choices value, so dict objects, set objects, custom containers, etc. are all supported."

解决方案

I do not think it is possible to pass a dictionary as an argument in the command line because there doesn't exist a conversion function from string to dict (EDIT: A hack is possible which gives similar behaviour, see below). What you are essentially telling python to do is:

dict("{'key1': 'value1'}")

Which if you try it out in the python console, does not work.

What the phrase:

"Any object that supports the in operator can be passed as the choices value, so dict objects, set objects, custom containers, etc. are all supported."

refers to is the choices argument that can be passed with the add_argument function - not to the type argument.

Your best bet is to probably accept your argument as a string and then convert it using the json capabilities of python:

parser.add_argument('-m', '--my-dict', type=str)
args = parser.parse_args()

import json
my_dictionary = json.loads(args.my_dict)

You can then pass a dictionary in the form of a string. You can try the json encoder/decoder out for yourself in the python console to see how it works:

>>>json.loads('{"value1":"key1"}')
{u'value1': u'key1'}

EDIT: hpaulj has pointed out to me that you can "hack" the type parameter by passing it json.loads which allows you to pass JSON that is similar looking to a dictionary.

import json
parser.add_argument('-d', '--my-dict', type=json.loads)
args = parse.parse_args()

mydict = args.my_dict  # Will return a dictionary

NOTE: The input format you pass is not the same as python dictionary but is probably similar enough for your use case.

The reason this works is actually quite interesting because internally argparse will just use the parameter value as a function to convert the argument. i.e. if type=int then it will use int(arg) or if type=json.loads then json.loads(arg)

This also means that you can pass any function which takes a single parameter in as the argument to type and perform custom conversions if you need to :)

这篇关于使用 argparse 和 python 接受字典作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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