[英]Safe use of eval() or alternatives - python
我总是对用任何语言使用eval感到厌倦,但我想不出一种更好的方法来做两件事。 从我读到的所有内容来看,evAl是evIl(很糟糕)。 任何想法表示赞赏。 我有一个带有字典的模块,该字典可以调用函数或设置属性,具体取决于您如何从另一个模块调用它
module Config
some_dict = {1: ["desc 1", "callfunction1()"],
2: ["desc2", "setattr(object, "attribute", "the fun things"]}
等等
module other
try:
i = int(input())
eval(Config.some_dict[i][1])
except ValueError:
print("nope")
我只是想知道是否有更安全的方法来做到这一点。
另外,如果我在程序运行时尝试调试:
try:
eval(input())
except:
pass
这是可接受的还是pythonic还是有更好的方法? 我是python的新手(我主要运行JSL,因此所有操作都由eval(parse())完成。
有一个更好的方法:使用一流的函数。
def func2():
setattr(object, "attribute", "the fun things")
some_dict = {
1: ["desc 1", callfunction1],
2: ["desc2", func2]
}
i = int(input())
Config.some_dict[i][1]()
如果您愿意使用lambda
或partial
可以减少混乱。 也就是说,您现有的解决方案不如eval
许多用法那么糟糕,因为它不评估任意用户输入,而是评估硬编码的字符串。 这完全是不必要的,非常缓慢且丑陋。
对于调试,有专用的调试器。 它们比临时的评估循环更有效。
我建议您将字典值变成某种可调用的对象。 例如,
some_dict = {
1: ["desc 1", callfunction1],
2: ["desc2", lambda: setattr(object, "attribute", "the fun things")]
}
然后,当您要使用字典中的元素时,只需调用它们:
name, func = some_dict[1]
func()
重要的是,字典中的每个值都必须具有相同的调用接口(例如,不带参数)。
您可以将函数作为值存储在字典中,因此只需为每个操作创建一个函数,然后在字典中查找并调用它。
def set_object_attr(obj=object, name='attribute', value='the fun things'):
setattr(obj, name, value)
some_dict = {1: ["desc 1", callfunction1],
2: ["desc 2", set_object_attr]}
# then wherever you are using this
some_dict[i][1]()
如您所见,由于callfunction1
已经是一个函数,因此您无需将其包装在另一个调用中。 您需要包装setattr()
调用,因为您需要能够不带任何参数地调用该函数。
我在上面编写了set_object_attr
函数以弄清楚发生了什么,但是在这种情况下,最好使用functools.partial
:
import functools
some_dict = {1: ["desc 1", callfunction1],
2: ["desc 2", functools.partial(setattr, object,
'attribute', 'the fun things')]}
为什么不简单地:
some_dict[2]['function'] = setattr
some_dict[2]['options'] = [object, "attribute", "value"]
然后,
if option = 'foo':
some_dict[2]['function'](*some_dict[2]['options'])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.