Python 如何从配置文件中指定的内容启用脚本中的函数?

Python 如何从配置文件中指定的内容启用脚本中的函数?,python,json,configuration,Python,Json,Configuration,我有以下JSON文件: { "add1":true, "add2":false, "add3":true } 以及以下Python程序: def add1n:返回n+1 def add2n:返回n+2 def add3n:返回n+3 def scoren: 打开'file.json','r'作为f: conf=json.loadf 对于键,conf.items中的值 如果值==True: add1和add3调用仅因为它们设置为True 返回add1n+add3n 正如在

我有以下JSON文件:

{
    "add1":true,
    "add2":false,
    "add3":true
}
以及以下Python程序:

def add1n:返回n+1 def add2n:返回n+2 def add3n:返回n+3 def scoren: 打开'file.json','r'作为f: conf=json.loadf 对于键,conf.items中的值 如果值==True: add1和add3调用仅因为它们设置为True 返回add1n+add3n 正如在代码中所写,我只想在配置JSON文件中设置为True时调用函数。这样做对吗?现有工具是否简化了这种方法,还是我必须手动编写每个案例?

您应该使用eval:


您可以通过调用eval来替换for循环


这假设json中的所有条目都映射到现有函数

您可以执行以下操作:

import json

def add1(n): return n+1
def add2(n): return n+2
def add3(n): return n+3

defs = {
    'add1' : add1,
    'add2' : add2,
    'add3' : add3
}

def score(n):
   with open('file.json', 'r') as f:
       conf = json.load(f)
       return sum(function(n) for name, function in defs.items() if conf[name])
如果您对lambdas满意,您甚至可以使用:

defs = {
    'add1' : lambda n: n+1,
    'add2' : lambda n: n+2,
    'add3' : lambda n: n+3
}

@Sayse有一个很好的方法,尽管我会更改求和行,这样当值为false时就不需要加0

            return sum(eval(f"{key}({n})") for key, value in conf.items() if value)
或者调用由字符串命名的函数的另一种方法是

            return sum(globals()[k](n) for k,v in conf.items() if v)
我不确定Python中的最佳实践是否支持某个版本。结果是一致的


请注意,您信任数据来指定程序调用的函数。不正确或恶意的数据可能会导致不确定和有害的行为,因此您可能需要检查密钥,以确保它们都指定了您打算以这种方式使用的功能之一。

如果配置文件中出现类似screw\u it:true的内容,您希望发生什么?如果既不存在add1:true也不存在add1:false怎么办?@Goyo我可能会引发一个我本可以捕捉到的错误,但我希望用户不要弄乱它,并输入我将指示的布尔值。然后尝试类似于@S.Pellegrino的操作。它比使用eval或globals更安全,更易于维护。我的add函数是一个更复杂问题的借口,我将它简化为一个可以理解的问题;我的第一个目标只是调用不同的函数,这些函数在参数中使用字符串并返回一个双精度值。但它似乎不适用于字符串,eval方法是否适用于作为参数给定的字符串?@ooj-001-eval所做的一切就是将您放入其中的内容作为python代码运行,因此,yesOk,谢谢,您的f是否特定于eval函数中必须编写的语法,或者您是否错误地使用了文件?因为在我的编辑器中,字母f高亮显示的方式使得它被理解为一个字符串。我使用了你的解决方案,效果很好,非常感谢!我认为回报声明会让你在街区外生活得更快乐。这与此无关。我将解析配置文件中的值,并在出现问题时引发异常,谢谢您的回答。
            return sum(eval(f"{key}({n})") for key, value in conf.items() if value)
            return sum(globals()[k](n) for k,v in conf.items() if v)