将列表传递给eval()
有没有办法把一个列表作为参数传给eval()函数?还是说我必须把它转换成字符串,然后在函数里再解析成列表呢?
我的简单例子是这样的:
eval("func1(\'" + fArgs + "\')")
我只是有点不确定,是否有更好的方法可以把fArgs当作列表来处理,而不是字符串。
注意:这个列表是从一个JSON响应中提供的。
编辑:好吧,这里我多提供一点我的类的内容,这样可以更好地理解我如何使用eval。
def test(arg):
print arg
#Add all allowed functions to this list to be mapped to a dictionary
safe_list = ['test']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
class Validate:
def __init__(self, Value, fName, fArgs):
eval(fName + "(\'" + fArgs + "\')", {"__builtins__":None},safe_dict)
我可能想错了,但我理解这是安全使用eval的方式,因为唯一可以调用的函数都是在safe_list字典中列出的。要运行的函数和它的参数是从一个JSON对象中提取出来的。参数应该是以列表的形式结构化的。那么把列表用", "连接起来,会被理解为实际的参数,还是仅仅被当作一个参数呢?
4 个回答
2
使用一个库来解析JSON输入可能比用eval更好,像这样:
import json
func1(json.loads(fArgs))
确保用户输入是正确的也是个好主意。
2
指定参数的方式如下所示是可行的:
root@parrot$ more test.py
def func1(*args):
for i in args:
print i
l = [1,'a',9.1]
func1(*l)
root@parrot$ python test.py
1
a
9.1
所以,除非我理解错了,否则不需要直接使用eval()。
7
如果你在用 Python 2.6.x 版本,那么你可以使用 json
模块(可以查看 Python 文档 19.2)。如果没有这个模块,你可以通过 Python 包索引找到 python-json。这两个包都能帮助你把 JSON 数据解析成合适的 Python 数据类型。
对于你提到的第二个问题,也就是根据消息调用一个函数,你可以这样做:
def foo():
print 'I am foo!'
def bar():
pass
def baz():
pass
funcs = {'func_a':foo, 'func_b':bar, 'func_c':baz}
funcs['func_a']()
这种方法比 eval
更安全一些,因为它可以防止一些不安全的 Python 库函数被注入到 JSON 中。不过,你还是需要小心,确保传给你函数的数据不会被操控,从而引发问题。