I\'m trying to set up a dictionary as optional argument (using argparse); the following line is what I have so far:
parser.add_argument(\'-i\',\'--image\', t
Combining the type=
piece from @Edd and the ast.literal.eval
piece from @Bradley yields the most direct solution, IMO. It allows direct retrieval of the argval and even takes a (quoted) default value for the dict:
parser.add_argument('--params', '--p', help='dict of params ', type=ast.literal.eval, default="{'name': 'adam'}")
args = parser.parse_args()
python test.py --p "{'town': 'union'}"
note the quotes on the dict value. This quoting works on Windows and Linux (tested with [t]csh).
dict=args.params
You could try:
$ ./script.py -i "{'name': 'img.png','voids': '#00ff00ff','0': '#ff00ff00','100%': '#f80654ff'}"
I haven't tested this, on my phone right now.
Edit: BTW I agree with @wim, I think having each kv of the dict as an argument would be nicer for the user.
Using simple lambda parsing is quite flexible:
parser.add_argument(
'--fieldMap',
type=lambda v: {k:int(v) for k,v in (x.split(':') for x in v.split(','))},
help='comma-separated field:position pairs, e.g. Date:0,Amount:2,Payee:5,Memo:9'
)
One of the simplest ways I've found is to parse the dictionary as a list, and then convert that to a dictionary. For example using Python3:
#!/usr/bin/env python3
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--image', type=str, nargs='+')
args = parser.parse_args()
if args.image is not None:
i = iter(args.image)
args.image = dict(zip(i, i))
print(args)
then you can type on the command line something like:
./script.py -i name img.png voids '#00ff00ff' 0 '#ff00ff00' '100%' '#f80654ff'
to get the desired result:
Namespace(image={'name': 'img.png', '0': '#ff00ff00', 'voids': '#00ff00ff', '100%': '#f80654ff'})
Here is a another solution since I had to do something similar myself. I use the ast
module to convert the dictionary, which is input to the terminal as a string, to a dict. It is very simple.
Say the following is called test.py
:
import argparse
import ast
parser = argparse.ArgumentParser()
parser.add_argument('--params', '--p', help='dict of params ',type=str)
options = parser.parse_args()
my_dict = options.params
my_dict = ast.literal_eval(my_dict)
print(my_dict)
for k in my_dict:
print(type(my_dict[k]))
print(k,my_dict[k])
Then in the terminal/cmd line, you would write:
python test.py --p '{"name": "Adam", "lr": 0.001, "betas": (0.9, 0.999)}'
{'name': 'Adam', 'lr': 0.001, 'betas': (0.9, 0.999)}
<class 'str'>
name Adam
<class 'float'>
lr 0.001
<class 'tuple'>
betas (0.9, 0.999)
A minimal example to pass arguments as a dictionary from the command line:
# file.py
import argparse
import json
parser = argparse.ArgumentParser()
parser.add_argument("-par", "--parameters",
required=False,
default=None,
type=json.loads
)
args = parser.parse_args()
print(args.parameters)
and in the terminal you can pass your arguments as a dictionary using a string format:
python file.py --parameters '{"a":1}'