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

后端 未结 4 1819
庸人自扰
庸人自扰 2020-11-27 04:45

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:

相关标签:
4条回答
  • 2020-11-27 05:06

    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
    
    0 讨论(0)
  • 2020-11-27 05:13

    I started off with @chander's excellent answer, but was running into issues with special character escaping, both at the shell/command level and within the python script. Saving the JSON to a file and then passing that filename as a parameter to the script would be a possible solution, but in my situation that was going to be rather complicated.

    So instead I decided to url encode the string at the argument level and decode it inside the Python script. This means that whatever is calling the python script needs to url-encode the command-line argument that is the JSON string. There are numerous online tools that let you sandbox with url-encoding a string. In my case, a nodejs script invokes the python script call and can easily url encode the JSON.

    Inside the Python script, it looks like this (you don't have to use argparse, but I like it):

    import json
    import argparse
    from urllib.parse import unquote
    
    # Set up CLI Arguments
    parser = argparse.ArgumentParser()
    
    # Required Arguments
    parser.add_argument("-c", "--config", required=True,
                        help="JSON configuration string for this operation")
    
    # Grab the Arguments
    args = parser.parse_args()
    
    jsonString = unquote(args.config)
    
    print(jsonString)
    
    config = json.loads(jsonString)
    
    print(config)
    
    0 讨论(0)
  • 2020-11-27 05:15

    Follow this steps to read either JSON or Dictionary as Command Line Argument without even Escaping the Double or single quotes for Python:

    1. Import the Windows32 API module for python like this:
      import win32.win32api

      If you don't have the module installed, then type: pip install pywin32 to install this module in your machine.

    2. Reading the command line arguments will be done by this line, the value of the command line arguments will be stored as a string in cmdArguments variable:

      cmdArguments = win32.win32api.GetCommandLine()

    3. It is always a good practise to pass the JSON/Dictionary in the last argument in the command line arguments, so suppose if you have the JSON/Dictionary passed as last argument in command line, then the following line can fetch the JSON/Dictionary as a separate argument and the JSON/Dictionary will be stored in a variable named jsonstr like this:

      jsonstr = ' '.join(cmdArguments.split(' ')[4:])

      Technically, the object gets split into separate arguments due to whitespaces and we need to combine it to make it as a single argument.

    4. Now, if you print the value of jsonstr then you will get the same JSON/Dictionary that was passed in the command line arguments section.

      The complete example Code for this is:

      import json
      import win32.win32api
      cmdArguments = win32.win32api.GetCommandLine()
      jsonstr = ' '.join(cmdArguments.split(' ')[4:])
      print(json.loads(jsonstr)) #To ensure that same JSON/Dictionary object is printed, json.loads() is used to convert JSON to DICT, you can ignore json.loads() if you want JSON object.
      
    5. The example command line arguments would be like this, where NameOfProgram is the name of the python script:

      py <NameOfProgram.py> {"Name":"Sample Name","Salary":"20 k","Class":"First-Class"}

      Now output will be:

      {'Name':'Sample Name','Salary':'20 k','Class':'First-Class'}
    0 讨论(0)
  • 2020-11-27 05:17

    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.)

    0 讨论(0)
提交回复
热议问题