将 Python 函数存储在 JSON 中

Con*_*son 5 python json user-defined-functions

假设我有一个这样的 JSON 文件:

{
  "x":5,
  "y":4,
  "func" : def multiplier(a,b):
               return a*d
}
Run Code Online (Sandbox Code Playgroud)

这过度简化了我想要尝试和做的事情,但基本上我试图
将 python UDF 故事化到 JSON 文件中。有没有办法做到这一点,以便当我这样做时:

with open('config.json') as f:
    data = json.load(f)
Run Code Online (Sandbox Code Playgroud)

我可以访问这些值并执行以下操作:

v1, v2 = data['x'], data['y']
mult = data['func']
print(mult(v1,v2))
Run Code Online (Sandbox Code Playgroud)

要获得预期输出:20

注意:据我所知,JSON 不存储函数,所以也许我可以将它存储为字符串,然后在我的 python 脚本中将字符串解析为函数?不太确定。

eat*_*ish 9

Python 有一个内置的模块名称marshal可以处理这个问题。

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)
Run Code Online (Sandbox Code Playgroud)

并且要拿回来...

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))
Run Code Online (Sandbox Code Playgroud)


sma*_*t3r 6

如果您确实需要将函数存储在外部 JSON 文件中,一种解决方案可能是将 lambda 函数存储为值并使用 eval函数从您的脚本中对其进行评估。

但请注意,eval在您的代码中使用可能很危险,请在使用前考虑安全隐患(请参阅realpython.com 上的这篇文章)。

配置文件

{
  "x": 5,
  "y": 4,
  "function": "lambda x, y : x * y"
}
Run Code Online (Sandbox Code Playgroud)

你的 Python 文件 (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)
Run Code Online (Sandbox Code Playgroud)

演示

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
Run Code Online (Sandbox Code Playgroud)