将列表传递给eval()

0 投票
4 回答
8731 浏览
提问于 2025-04-15 16:34

有没有办法把一个列表作为参数传给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 中。不过,你还是需要小心,确保传给你函数的数据不会被操控,从而引发问题。

撰写回答