Pregunta

¿Hay alguna forma de pasar una lista como argumento de función a eval () O tengo que convertirla en una cadena y luego analizarla como una lista en la función?

Mi ejemplo simple se ve así:

 eval("func1(\'" + fArgs + "\')")

Simplemente no estoy seguro de si hay una mejor manera de tomar fArgs como una lista en lugar de una cadena

Nota: La lista se proporciona a partir de una respuesta JSON

EDITAR: Ok, aquí hay un poco más de mi clase, así que hay una mejor comprensión de cómo estoy usando 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)

Puedo estar equivocado al pensar esto, pero a mi entender, este es un uso seguro de eval porque las únicas funciones que se pueden invocar son las que se enumeran en el diccionario safe_list. La función a ejecutar y los argumentos para esa función se extraen de un objeto JSON. Los argumentos deben estructurarse como una lista. Se unirá a la lista junto con " ;, " ser interpretado como argumentos reales o simplemente como un solo argumento?

¿Fue útil?

Solución

Si está usando Python 2.6.x, entonces debería poder usar el módulo json (vea py doc 19.2 ). Si no, entonces hay python-json disponible a través del índice del paquete python. Ambos paquetes proporcionarán un lector para analizar datos JSON en un tipo de datos Python apropiado.

Para su segundo problema de llamar a una función determinada por un mensaje, puede hacer lo siguiente:

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']()

Este enfoque puede ser un poco más seguro que eval porque evita que las funciones de la biblioteca de Python 'inseguras' se inyecten en el JSON. Sin embargo, aún debe tener cuidado de que los datos suministrados a sus funciones no puedan manipularse para causar problemas.

Otros consejos

Especificar parámetros de la siguiente manera funciona:

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

entonces, no hay necesidad directa de eval (), a menos que esté malinterpretando algo.

Usar una biblioteca para analizar la entrada JSON puede ser un mejor enfoque que eval, algo como:

import json
func1(json.loads(fArgs))

Afirmar que la entrada del usuario es correcta también sería una buena idea.

Los otros tienen un buen punto, que no deberías usar eval . Pero, si debes:

eval("func1(%s)" % ", ".join(fArgs))

llamará a la función con todos los argumentos en la lista. Esto:

eval("func1([%s])" % ", ".join(fArgs))

lo llamará con la lista de argumentos en un solo argumento. ¿Quizás incluso quieres esto?

eval("func1([%s])" % ", ".join(map(eval, fArgs)))

¿cuál eval también los argumentos?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top