Say I have a JSON file as such:
{
"x":5,
"y":4,
"func" : def multiplier(a,b):
return a*d
}
This over-simplifies what I want to try and do, but basically I am attempting
to story a python UDF into a JSON file. Is there a way to do this so that when I
do:
with open('config.json') as f:
data = json.load(f)
I can access those values and do something like:
v1, v2 = data['x'], data['y']
mult = data['func']
print(mult(v1,v2))
To get expected output: 20
NOTE: To my understanding JSON doesn't store functions, so maybe I can store it as a string, and then in my python script parse the string into a function? Not too sure.
Python has a built in module name marshal
that can handle this.
import marshal, ujson as json
def multiplier(a, b):
return a * b
x = {
"x":5,
"y":4,
"func" : marshal.dumps(multiplier.func_code)
}
x = json.dumps(x)
print(x)
And to get it back...
x = json.loads(x)
x = marshal.loads(x['func'])
# maybe save the function name in dict
func = types.FunctionType(x, globals(), "some_func_name")
print(func(2,4))
If you really need to store a function in an external JSON file, one solution could be to store a lambda function as a value and use the eval
function to evaluate it from your script.
But be aware that using eval
in your code could be dangerous, please consider the security implications before using it (see this article from realpython.com).
config.json
{
"x": 5,
"y": 4,
"function": "lambda x, y : x * y"
}
Your Python file (test.py)
import json
def run():
"""Run function from JSON config."""
with open("config.json") as f:
data = json.load(f)
x, y = data["x"], data["y"]
multiplier = eval(data["function"])
return multiplier(x, y)
if __name__ == "__main__":
result = run()
print(result)
Demo
In[2]: ls
test.py
config.json
In[3]: import json
In[4]: def run():
...: """Run function from JSON config."""
...:
...: with open("config.json") as f:
...: data = json.load(f)
...:
...: x, y = data["x"], data["y"]
...: multiplier = eval(data["func"])
...: return(multiplier(x, y))
...:
In[5]: run()
20
Something that is worth trying is just saving it as a string.
You can do stuff like
my_func = "
def function(a,b):
constant = {input_var}
return a*b + constant
"
my_func.format(input_var = 5)
exec(my_func)
function(1,2) # will return 7
This will create object of the function that you can call. Not really sure what you are trying to do but creating a json file like below should give you what you want to do: (I added the 'func' wrapper because I am assuming you will have multiple functions in one JSON)
function_json = {
'func': {
'x':5
'y':4
'multiplier':
'def multiplier(a,b):
return a*b'
}
x=function_json['func']['x']
y=function_json['func']['y']
exec(function_json['func']['multiplier'])
multiplier(x,y) # will return 20
hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With