Передача списка в 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.Аргументы должны быть структурированы в виде списка. Будет ли объединение списка с помощью «,» интерпретироваться как фактические аргументы или просто один аргумент?
Решение
Если вы используете Python 2.6.x, вы сможете использовать json
модуль (см. документ py 19.2).Если нет, то есть Python-JSON доступен через индекс пакета Python.Оба этих пакета предоставляют программу чтения для анализа данных 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.Однако вам все равно нужно быть осторожным, чтобы данные, передаваемые в ваши функции, не могли быть изменены и вызвать проблемы.
Другие советы
Указание параметров следующим образом работает:
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() нет, если только я чего-то не понимаю.
Использование библиотеки для анализа ввода JSON может быть лучшим подходом, чем eval, например:
import json
func1(json.loads(fArgs))
Утверждение, что пользовательский ввод верен, также было бы хорошей идеей.
У остальных есть хорошая точка зрения, которую вам не следует использовать. eval
.Но если вам необходимо:
eval("func1(%s)" % ", ".join(fArgs))
вызовет функцию со всеми аргументами в списке.Этот:
eval("func1([%s])" % ", ".join(fArgs))
вызовет его со списком аргументов всего в одном аргументе.Может быть, ты даже хочешь этого?
eval("func1([%s])" % ", ".join(map(eval, fArgs)))
которые бы eval
аргументы тоже?