Python argparse dict arg

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29986185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:15:14  来源:igfitidea点击:

Python argparse dict arg

pythondictionaryargparse

提问by orion_tvv

I want to receive a dict(str -> str)argument from the command line. Does argparse.ArgumentParserprovide it? Or any other library?

我想dict(str -> str)从命令行接收参数。不argparse.ArgumentParser提供呢?或者其他图书馆?

For the command line:

对于命令行:

program.py --dict d --key key1 --value val1 --key key2 --value val2

I expect the following dictionary:

我期待以下字典:

d = {"key1": "val1", "key2": "val2"}

采纳答案by storm_m2138

Here's another solution using a custom action, if you want to specify dict key pairs together comma-separated --

这是使用自定义操作的另一个解决方案,如果您想将 dict 键对一起指定为逗号分隔 -

import argparse
import sys
parser = argparse.ArgumentParser(description='parse key pairs into a dictionary')

class StoreDictKeyPair(argparse.Action):
     def __call__(self, parser, namespace, values, option_string=None):
         my_dict = {}
         for kv in values.split(","):
             k,v = kv.split("=")
             my_dict[k] = v
         setattr(namespace, self.dest, my_dict)

parser.add_argument("--key_pairs", dest="my_dict", action=StoreDictKeyPair, metavar="KEY1=VAL1,KEY2=VAL2...")

args = parser.parse_args(sys.argv[1:])
print args

Running:

跑步:

python parse_kv.py --key_pairs 1=2,a=bbb,c=4 --key_pairs test=7,foo=bar

Output:

输出:

Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})

If you want to use nargsinstead of comma-separated values in string:

如果要在字符串中使用nargs而不是逗号分隔值:

class StoreDictKeyPair(argparse.Action):
     def __init__(self, option_strings, dest, nargs=None, **kwargs):
         self._nargs = nargs
         super(StoreDictKeyPair, self).__init__(option_strings, dest, nargs=nargs, **kwargs)
     def __call__(self, parser, namespace, values, option_string=None):
         my_dict = {}
         print "values: {}".format(values)
         for kv in values:
             k,v = kv.split("=")
             my_dict[k] = v
         setattr(namespace, self.dest, my_dict)

parser.add_argument("--key_pairs", dest="my_dict", action=StoreDictKeyPair, nargs="+", metavar="KEY=VAL")

args = parser.parse_args(sys.argv[1:])
print args

Running

跑步

python arg_test4.py --key_pairs 1=2 a=bbb c=4 test=7 foo=bar

Outputs:

输出:

values: ['1=2', 'a=bbb', 'c=4', 'test=7', 'foo=bar']
Namespace(my_dict={'1': '2', 'a': 'bbb', 'c': '4', 'test': '7', 'foo': 'bar'})

回答by divyum

Python receives arguments in the form of an array argv. You can use this to create the dictionary in the program itself.

Python 以数组的形式接收参数argv。您可以使用它在程序本身中创建字典。

import sys
my_dict = {}
for arg in sys.argv[1:]:
    key, val=arg.split(':')[0], arg.split(':')[1]
    my_dict[key]=val

print my_dict

For command line:

对于命令行:

python program.py key1:val1 key2:val2 key3:val3

Output:

输出:

my_dict = {'key3': 'val3', 'key2': 'val2', 'key1': 'val1'}

Note: args will be in string, so you will have to convert them to store numeric values.

注意:args 将在字符串中,因此您必须将它们转换为存储数值。

I hope it helps.

我希望它有帮助。

回答by skyline75489

As for the current libraries like argparse, docoptand click, none of them support using dictargs. The best solution I can think of is to make a custom argparse.Actionto support it youself:

对于当前的库,如argparsedocoptclick,它们都不支持使用dictargs。我能想到的最佳解决方案是自定义argparse.Action以支持它自己:

import argparse

class MyAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        super(MyAction, self).__init__(option_strings, dest, nargs, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        print '%r %r %r' % (namespace, values, option_string)
        value_dict = {}
        values.reverse()
        while len(values) > 0:
            v = eval(values.pop()).lstrip('--') # This is like crazy hack, I know.
            k = eval(values.pop())
            value_dict[k] = v

        setattr(namespace, self.dest, value_dict)

parser = argparse.ArgumentParser()
parser.add_argument('-d', action=MyAction, nargs='*')
args = parser.parse_args('-d "--key" "key1" "--value" "val1" "--key" "key2" "--value" "val2"'.split())

print(args)

回答by chepner

I would use something like this:

我会使用这样的东西:

p = argparse.ArgumentParser()
p.add_argument("--keyvalue", action='append',
               type=lambda kv: kv.split("="), dest='keyvalues')

args = p.parse_args("--keyvalue foo=6 --keyvalue bar=baz".split())
d = dict(args.keyvalues)

You could create a custom action which would "append" a parsed key-value pair directly into a dictionary, rather than simply accumulating a list of (key, value)tuples. (Which I see is what skyline75489 did; my answer differs in using a single --keyvalueoption with a custom type instead of separate --keyand --valueoptions to specify pairs.)

您可以创建一个自定义操作,将已解析的键值对直接“附加”到字典中,而不是简单地累积(key, value)元组列表。(我看到的是什么skyline75489做;在使用单我的回答不同--keyvalue选项和自定义的类型,而不是单独的--key--value。选项来指定对)

回答by hpaulj

A straight forward way of parsing an input like:

解析输入的直接方法,如:

program.py --dict d --key key1 --value val1 --key key2 --value val2

is:

是:

parser=argparse.ArgumentParser()
parser.add_argument('--dict')
parser.add_argument('--key', action='append')
parser.add_argument('--value', action='append')
args = parser.parse_args()

which should produce (if my mental parser is correct)

应该产生(如果我的心理解析器是正确的)

args = Namespace(dict='d', key=['key1','key2'], value=['value1','value2'])

You should be able construct a dictionary from that with:

您应该能够从中构建一个字典:

adict = {k:v for k, v in zip(args.key, args.value)}

Using args.dictto assign this to a variable with that name requires some un-python trickery. The best would be to create a element in another dictionary with this name.

使用args.dict将其分配给具有该名称的变量需要一些非 Python 技巧。最好的办法是在另一个字典中用这个名字创建一个元素。

another_dict = {args.dict: adict}

This solution doesn't perform much error checking. For example, it doesn't make sure that there are the same number of keys and values. It also wouldn't let you create multiple dictionaries (i.e. repeated --dictarguments). It doesn't require any special order. --dictcould occur after a --key key1pair. Several --valuearguments could be together.

此解决方案不会执行太多错误检查。例如,它不能确保键和值的数量相同。它也不会让您创建多个字典(即重复--dict参数)。它不需要任何特殊命令。 --dict可能发生在一--key key1对之后。几个--value参数可以放在一起。

Tying the key=valuetogether as chepnerdoes gets around a number of those problems.

key=value它们捆绑在一起chepner可以解决许多这些问题。

回答by miszel

Python one-line argparse dictionary arguments argparse_dictionary.py

Python 单行 argparse 字典参数argparse_dictionary.py

# $ python argparse_dictionary.py --arg_dict=1=11,2=22;3=33 --arg_dict=a=,b,c=cc,=dd,=ee=,
# Namespace(arg_dict={'1': '11', '2': '22', '3': '33', 'a': '', 'c': 'cc', '': 'dd'})

import argparse

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('--arg_dict', action=type(b'', (argparse.Action,), dict(__call__=lambda self, parser, namespace, values, option_string: getattr(namespace, self.dest).update(dict([v.split('=') for v in values.replace(';', ',').split(',') if len(v.split('=')) == 2])))), default={}, metavar='KEY1=VAL1,KEY2=VAL2;KEY3=VAL3...')
print(arg_parser.parse_args())

回答by Clemens69

just another easy way:

只是另一种简单的方法:

parser = argparse.ArgumentParser()
parser.add_argument('--key1')
parser.add_argument('--key2')
args = parser.parse_args()
my_dict = args.__dict__

回答by Brian

There is a simple solution in Python 3.6 if you're simply trying to convert argparse input to a dictionary. An example is as follows:

如果您只是想将 argparse 输入转换为字典,那么 Python 3.6 中有一个简单的解决方案。一个例子如下:

import argparse 

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input', help='the path to the input file')
parser.add_argument('-o', '--output', help='the path to the output file')
args = parser.parse_args()

arguments = dict(args._get_kwargs())

for k, v in arguments.items():
    print(k, v) 

Given command line input such as python3 script_name.py --input 'input.txt' --output 'output.txt'the code would output to terminal:

给定命令行输入(例如python3 script_name.py --input 'input.txt' --output 'output.txt'代码将输出到终端):

input input.txt
output output.txt