2

I have a JSON configuration file which looks something like this:

{
    "generic": {
        "loglevel": 2,
         ...
    },
    "clients": [
        {
            "type": "foo",
            "bar": {
                "bar_1": 0.7,
                "bar_2": 0.95
            },
            ...
        },
        {
            "type": "foo",
            ...
        }
    ]
}

I can modify the contents and store the modified version of it using:

import json
with open("sample.cfg", "r") as config_file:
    config = json.load(config_file)

config["clients"][0]["bar"]["bar_1"] = 100

with open("modified.cfg", "w") as config_file:
    config_file.write(json.dumps(config))

But I would like to modify the file based on some input. Let's say the input is a string changestring:

changestring = 'clients,0,bar,bar_1:1,2,3'
keyval=changestring.split(':')
keys = keyval[0].split(',')
vals = keyval[1].split(',')

But now I don't know how to use the keys in order to access the config path. Is this actually the right way to do this? Or maybe there is a different way to handle it? Thanks.

2
  • 1
    The right way to do this is to load the JSON file into a dictionary, modify, and write back as JSON to a file - but you already know this. Why would you want to modify the file directly? Commented Apr 11, 2016 at 4:42
  • This is a config file. I would like to run parameter sweep on some application. This will run on the Oracle Grid Engine, so I want to redistribute parameters to different jobs. Commented Apr 11, 2016 at 4:50

2 Answers 2

2

This is certainly a viable solution. It will work, but if actual users supply the change string, you probably want some way to ensure that the string is valid.

You also probably want to distinguish between integer indices and string indices!

Assuming your code, you could do the following:

import json
with open("sample.cfg", "r") as config_file:
  config = json.load(config_file)

changestring = 'clients,0,bar,bar_1:1,2,3'
keyval = changestring.split(':')
keys = keyval[0].split(',')
vals = keyval[1].split(',')

# Move our "pointer"
obj = config
for key in keys[:-1]:
  try: obj = obj[key]
  except TypeError:
    # Probably want a more general solution
    obj = obj[int(key)]

# Update value
obj[keys[-1]] = vals

with open("modified.cfg", "w") as config_file:
  config_file.write(json.dumps(config))

Python has aliasing, so by updating a variable down the "index" tree (but not all the way), we can get a mutable copy of what we actually want to modify. This should work for any "depth" of keys supplied. I tested this on python2.7.

Sign up to request clarification or add additional context in comments.

Comments

0

if i am interpreting your question right

your keys and vals list will look like this

keys = ["clients", "0", "bar", "bar_1"]
vals = ["1", "2", "3"]

so to update the value of config["clients"][0]["bar"]["bar_1"] you can do like this

config[keys[0]][keys[1]][keys[2]][keys[3]] = vals[index]

index will be the index of value in vals list with which you want to update your json

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.