0

I have a dictionary that contains references to different functions. I was trying to make my code more readable and make it easier to add functions to this dictionary. I was trying to convert my dictionary into a .json file but it gives an error once it tries to add the function.

This is a simplified version of my code:

import json

def func1():  print("func1")
def func2():  print("func2")
def func3():  print("func3")

testDict = {
    "value1":[func1, "test1"],
    "value3":[func2, "test2"],
    "value3":[func3, "test3"],
}

with open("test.json", "w") as fw:
    json.dump(testDict, fw, indent=2)

This is the code i made to read the .json file:

with open("test.json", "r+") as fr:
    testDict2 = json.load(fr)

However when i try to create the file it stops once it reaches the reference to the first function:

{
  "value1": [

How do i fix this and is it even possible?

poendie
  • 21
  • 5
  • What is your purpose to dump `function` as a json? – JayPeerachai Mar 18 '22 at 16:53
  • The function is an object that is specific to python so encoding it in json doesn't make sense. If you change that to be `"value1":["func1", "test1"],` where the function is refererred to as a string, then it could be jsonified BUT then you need to `eval()` which invites [a lot of risk](https://stackoverflow.com/questions/661084/security-of-pythons-eval-on-untrusted-strings). – JNevill Mar 18 '22 at 16:54
  • I want to make it easier for me to add additional functions to my dictionary, instead of searching for the dictionary in my code i can just add it in a .json file. – poendie Mar 18 '22 at 16:56
  • But you still need to define that function in the script, which defeats the purpose – matszwecja Mar 18 '22 at 16:58
  • Well yeah but its more for readability, instead of a random dict in my code i have a seperate file for that stuff. – poendie Mar 18 '22 at 17:15
  • Did you look at the exception raised at that point? "TypeError: Object of type function is not JSON serializable" – chepner Mar 20 '22 at 15:31
  • Yep that was the problem, that is fixed now by just turning it into a string but now i need a way to call the functions. – poendie Mar 21 '22 at 11:44

3 Answers3

0

According to: https://www.w3schools.com/js/js_json_datatypes.asp "In JSON, values must be one of the following data types:

  • a string
  • a number
  • an object (JSON object)
  • an array
  • a boolean
  • null

JSON values cannot be one of the following data types:

  • a function
  • a date
  • undefined"

Python functions place is in .py files, because that is where they have any meaning. JSON is supposed to be language-independant

matszwecja
  • 6,357
  • 2
  • 10
  • 17
0

No, its not straightforwardly possible. The JSON format provides no means for serializing functions. You could potentially do this by leveraging the inspect module to get the string source of a function and then eval, but that still wouldn't behave correctly in many cases, for example, when you have a captured reference to a variable in enclosing scope in your function.

It's worth noting that in general, attempts to execute serialized code present a lot of security risks. In many applications, JSON formatted input is provided by the user. Allowing the user to provide functions as input creates an arbitrary code execution vulnerability.

Nick Bailey
  • 3,078
  • 2
  • 11
  • 13
0

globals()"funcName" works

poendie
  • 21
  • 5