type=dict in argparse.add_argument()

后端 未结 11 694
既然无缘
既然无缘 2020-12-03 07:02

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         


        
11条回答
  •  时光取名叫无心
    2020-12-03 07:45

    General Advice: DO NOT USE eval.

    If you really have to ... "eval" is dangerous. Use it if you are sure no one will knowingly input malicious input. Even then there can be disadvantages. I have covered one bad example.

    Using eval instead of json.loads has some advantages as well though. A dict doesn't really need to be a valid json. Hence, eval can be pretty lenient in accepting "dictionaries". We can take care of the "danger" part by making sure that final result is indeed a python dictionary.

    import json
    import argparse
    
    tests = [
      '{"name": "img.png","voids": "#00ff00ff","0": "#ff00ff00","100%": "#f80654ff"}',
      '{"a": 1}',
      "{'b':1}",
      "{'$abc': '$123'}",
      '{"a": "a" "b"}' # Bad dictionary but still accepted by eval
    ]
    def eval_json(x):
      dicti = eval(x)
      assert isinstance(dicti, dict)
      return dicti
    
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--input', type=eval_json)
    for test in tests:
      args = parser.parse_args(['-i', test])
      print(args)
    

    Output:

    Namespace(input={'name': 'img.png', '0': '#ff00ff00', '100%': '#f80654ff', 'voids': '#00ff00ff'})
    Namespace(input={'a': 1})
    Namespace(input={'b': 1})
    Namespace(input={'$abc': '$123'})
    Namespace(input={'a': 'ab'})
    

提交回复
热议问题