Is there any way of saving a variable to a json file that gets saved as a variable and opened as a usable variable later:
import json
variable = 123
test = {
1 : 1*variable,
2 : 2*variable,
3 : 3*variable
}
with open('json_data_Test.json', 'w') as outfile:
json.dump(test,outfile)
variable = 200
with open('json_data_Test.json', 'r') as outfile:
test2 = json.load (outfile)
print(test2)
Output:
{'1': 123, '2': 246, '3': 369}
Desired Output:
{'1': 200, '2': 400, '3': 600}
The aim is to when the json file is reopened and brought into a dictionary, the values are changeable based on the new value of variable
.
CodePudding user response:
No, because the multiplication operation was calculated and the result of that operation was stored in your json, which has no idea what variable
is.
In fact, integers aren't mutable, so even if you ignore the json part and stick to python, once you have set the value of variable = 123
and used it in another = variable
, modifying variable
isn't going to change the value of another
.
If you know for sure that the three keys in your json dict are integer multiples of a single variable, you could calculate the value of the greatest common divisor using math.gcd()
. Then, divide each value by this and multiply by the new value of variable
.
with open('json_data_Test.json', 'r') as outfile:
test2 = json.load (outfile)
old_variable = math.gcd(test2['1'], test2['2'])
for key in test2:
test2[key] *= (variable / old_variable)
Now, test2
is {'1': 200.0, '2': 400.0, '3': 600.0}
If you cannot guarantee that the GCD of the values in your dict will be the old variable
, you should probably change the output object to save the value of variable
in your json:
variable = 123
out_obj = {
"variable": variable,
"test": {
1 : 1*variable,
2 : 2*variable,
3 : 3*variable
}
}
with open('json_data_Test.json', 'w') as outfile:
json.dump(out_obj,outfile)
variable = 200
with open('json_data_Test.json', 'r') as outfile:
in_obj = json.load(outfile)
old_variable = in_obj["variable"]
test2 = in_obj["test"]
for key in test2:
test2[key] *= (variable / old_variable)
CodePudding user response:
If you need something generic, and you DO NOT TAKE ANY INPUT FROM AN UNTRUSTED USER, you can use python's eval
, and save the values as strings which will later be reevaluated with the new value of variable
.
I suggest something like this:
import json
variable = 123
test = {
1 : '1*<variable>',
2 : '2*<variable>',
3 : '3*<variable>',
4 : ['<variable> 5', '<variable> 6'],
}
with open('json_data_Test.json', 'w') as outfile:
outfile.write(json.dumps(test))
variable = 200
def evaluate(d):
# recursively go through every value of the dictionary, and replace the <variable> wildcard with it's value, and then use `eval`.
if type(d) == str:
return eval(d.replace('<variable>', str(variable)))
for k, v in d.items():
if type(v) in [list, tuple]:
d[k] = [evaluate(i) for i in v]
else:
d[k] = evaluate(v)
return d
with open('json_data_Test.json', 'r') as outfile:
data = outfile.read()
evaluated = evaluate(json.loads(data))
print(evaluated)
Again, if you accept any sort of untrusted user input, avoid using this at all costs, as it will allow that user to run arbitrary python code, which is a huge security vulnerability.