You can definitely get in something that looks like a dictionary literal into the argument parser, but you've got to quote it so when the shell parses your command line, it comes in as
- a single argument instead of many (the space character is the normal argument delimiter)
- properly quoted (the shell removes quotes during parsing, because it's using them for grouping)
So something like this can get the text you wanted into your program:
python MYSCRIPT.py -i "{\"name\": \"img.png\", \"voids\": \"#00ff00ff\",\"0\": \"#ff00ff00\",\"100%\": \"#f80654ff\"}"
However, this string is not a valid argument to the dict constructor; instead, it's a valid python code snippet. You could tell your argument parser that the "type" of this argument is eval
, and that will work:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i','--image', type=eval, help='Generate an image map...')
args = parser.parse_args()
print args
and calling it:
% python MYSCRIPT.py -i "{\"name\": \"img.png\", \"voids\": \"#00ff00ff\",\"0\": \"#ff00ff00\",\"100%\": \"#f80654ff\"}"
Namespace(image={'0': '#ff00ff00', '100%': '#f80654ff', 'voids': '#00ff00ff', 'name': 'img.png'})
But this is not safe; the input could be anything, and you're evaluating arbitrary code. It would be equally unwieldy, but the following would be much safer:
import argparse
import ast
parser = argparse.ArgumentParser()
parser.add_argument('-i','--image', type=ast.literal_eval, help='Generate an image map...')
args = parser.parse_args()
print args
This also works, but is MUCH more restrictive on what it will allow to be eval
'd.
Still, it's very unwieldy to have the user type out something, properly quoted, that looks like a python dictionary on the command line. And, you'd have to do some checking after the fact to make sure they passed in a dictionary instead of something else eval-able, and had the right keys in it. Much easier to use if:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--image-name", required=True)
parser.add_argument("--void-color", required=True)
parser.add_argument("--zero-color", required=True)
parser.add_argument("--full-color", required=True)
args = parser.parse_args()
image = {
"name": args.image_name,
"voids": args.void_color,
"0%": args.zero_color,
"100%": args.full_color
}
print image
For:
% python MYSCRIPT.py --image-name img.png --void-color \#00ff00ff --zero-color \#ff00ff00 --full-color \#f80654ff
{'100%': '#f80654ff', 'voids': '#00ff00ff', 'name': 'img.png', '0%': '#ff00ff00'}
echo ./script.py -i {'name': ...
) you'll see what python is seeing (mainly it is not receiving any quotes). In your case that there is no$
in your param (that could be interpreted by the shell as an enviroment variable) you can surround your dict with double quotes:./script.py -i "{'name': 'img.png', ....}"
– Seattle