How to pass dictionary as command line argument to Python script?

How to pass dictionary as command line argument to Python script? I need to get dictionary where key is string and value is list of some elements – for example to look like:

command_line_arguments = {"names" : ["J.J.", "April"], "years" : [25, 29]}

I have tried like

if __name__ == '__main__':
    args = dict([arg.split('=') for arg in sys.argv[2:]]) # also tried with 1 but doesn't work
    main(args)

and I am calling script like

$ python saver.py names=["J.J.", "April"] years=[25, 29]

but it doesn't work, dictionary has length 0 and need 2. Can anyone help me to pass and create dictionary in main.


The important thing to note here is that at the command line you cannot pass in python objects as arguments. The current shell you are using will parse the arguments and pass them in according to it's own argument parsing rules.

That being said, you cannot pass in a python dictionary. However, things like JSON can allow you to get pretty darn close.

JSON - or JavaScript Object Representation is a way of taking Python objects and converting them into a string-like representation, suitable for passing around to multiple languages. That being said, you could pass in a string like this:

python saver.py '{"names": ["J.J.", "April"], "years": [25, 29]}'

In your python script, do this:

import json
data=json.loads(argv[1])

This will give you back a dictionary representing the data you wanted to pass in.

Likewise, you can take a python dictionary and convert it to a string:

import json
data={'names': ["J.J.", "April"], 'years': [25,29]}
data_str=json.dumps(data)

There are other methods of accomplishing this as well, though JSON is fairly universal. The key thing to note is that regardless of how you do it - you won't be passing the dictionary into Python, - you'll be passing in a set of arguments (which will all be strings) that you'll need to somehow convert into the python type you need.

@EvanZamir - note that (generally) in a shell, you need to escape quotes if they appear in your quoted string. In my example, I quote the JSON data with single quotes, and the json string itself uses double quotes, thereby obviating the need for quotes.

If you mix quotes (use double quotes to quote the argument, and double quotes inside), then the shell will require it to be escaped, otherwise the first double quote it encounters is considered the "closing quote" for the argument. Note in the example, I use single quotes to enclose the JSON string, and double quotes within the string. If I used single quotes in the string, I would need to escape them using a backslash, i.e.:

python saver.py '{"names": ["J.J.", "April\'s"], "years": [25, 29]}'

or

python saver.py "{\"names\": [\"J.J.\", \"April's\"], \"years\": [25, 29]}"

Note the quoting stuff is a function of your shell, so YMMV might vary (for example, if you use some exec method to call the script, escaping might not be required since the bash shell might not be invoked.)


Here's another method using stdin. That's the method you want for a json cgi interface (i.e. having a web server pass the request to your script):

Python:

 import json, sys
 request = json.load( sys.stdin )
...

To test your script from a Linux terminal:

echo '{ "key1": "value 1", "key2": "value 2" }' | python myscript.py

To test your script from a Windows terminal:

echo { "key1": "value 1", "key2": "value 2" } | python myscript.py