python command line arg_Python argparse dict arg

问题

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

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"}

回答1:

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

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 nargs instead of comma-separated values in string:

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'})

回答2:

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 --keyvalue option with a custom type instead of separate --key and --value options to specify pairs.)

回答3:

just another easy way:

parser = argparse.ArgumentParser()

parser.add_argument('--key1')

parser.add_argument('--key2')

args = parser.parse_args()

my_dict = args.__dict__

回答4:

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

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.

I hope it helps.

回答5:

Python one-line argparse dictionary arguments 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())

回答6:

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:

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:

input input.txt

output output.txt

回答7:

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.dict to 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.

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 --dict arguments). It doesn't require any special order. --dict could occur after a --key key1 pair. Several --value arguments could be together.

Tying the key=value together as chepner does gets around a number of those problems.

回答8:

As for the current libraries like argparse, docopt and click, none of them support using dict args. The best solution I can think of is to make a custom argparse.Action to support it youself:

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)

来源:https://stackoverflow.com/questions/29986185/python-argparse-dict-arg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值