evaluar en Python

La función Python eval() analiza el argumento de la expresión y lo evalúa como una expresión de Python y ejecuta la expresión de Python (código) dentro del programa.

Sintaxis de Python eval()

eval(expresión, globales=Ninguno, locales=Ninguno)

Parámetros de Python eval()

  • expresión: esta string se analiza y evalúa como una expresión de Python
  • globales (opcional): un diccionario para especificar los métodos y variables globales disponibles.
  • locales (opcional): otro diccionario para especificar los métodos y variables locales disponibles.

Ejemplo 1: Ejemplo para demostrar el uso de eval()

Explorémoslo con la ayuda de un programa Python simple. function_creator es una función que evalúa las funciones matemáticas creadas por el usuario.

Python3

from math import *
 
def secret_function():
    return "Secret key is 1234"
 
def function_creator():
 
    # expression to be evaluated
    expr = input("Enter the function(in terms of x):")
 
    # variable used in expression
    x = int(input("Enter the value of x:"))
 
    # evaluating expression
    y = eval(expr)
 
    # printing evaluated result
    print("y = {}".format(y))
 
 
if __name__ == "__main__":
    function_creator()

Producción:

Enter the function(in terms of x):x*(x+1)*(x+2)
Enter the value of x:3
y = 60

Analicemos un poco el código:

  • La función anterior toma cualquier expresión en la variable x como entrada.
  • Luego, el usuario debe ingresar un valor de x .
  • Finalmente, evaluamos la expresión de python usando la función integrada eval() pasando expr como argumento.

Ejemplo 2: Operaciones matemáticas usando la función eval

Python3

evaluate = 'x*(x+1)*(x+2)'
print(evaluate)
print(type(evaluate))
 
x = 3
print(type(x))
 
expression = eval(evaluate)
print(expression)
print(type(expression))
Producción

x*(x+1)*(x+2)
<class 'str'>
<class 'int'>
60
<class 'int'>

Problemas de vulnerabilidad con eval

Nuestra versión actual de function_creator tiene algunas vulnerabilidades. El usuario puede exponer fácilmente valores ocultos en el programa o llamar a una función peligrosa, ya que eval ejecutará cualquier cosa que se le pase.

Por ejemplo, si ingresas así:

Enter the function(in terms of x):secret_function()

Enter the value of x:0

Obtendrá la salida:

y = Secret key is 1234

Además, considere la situación cuando haya importado el módulo os en su programa python. El módulo os proporciona una forma portátil de utilizar las funcionalidades del sistema operativo, como leer o escribir un archivo. Un solo comando puede eliminar todos los archivos en su sistema. Por supuesto, en la mayoría de los casos (como los programas de escritorio), el usuario no puede hacer más de lo que podría hacer si escribiera su propio script de python, pero en algunas aplicaciones (como aplicaciones web, computadoras de quiosco), ¡esto podría ser un riesgo!

La solución es restringir eval solo a las funciones y variables que queremos que estén disponibles.

Hacer que la evaluación sea segura

La función eval viene con la facilidad de pasar explícitamente una lista de funciones o variables a las que puede acceder. Necesitamos pasarlo como un argumento en forma de diccionario.

Python3

from math import *
 
def secret_function():
    return "Secret key is 1234"
 
def function_creator():
 
    # expression to be evaluated
    expr = input("Enter the function(in terms of x):")
 
    # variable used in expression
    x = int(input("Enter the value of x:"))
 
    # passing variable x in safe dictionary
    safe_dict['x'] = x
 
    # evaluating expression
    y = eval(expr, {"__builtins__": None}, safe_dict)
 
    # printing evaluated result
    print("y = {}".format(y))
 
 
if __name__ == "__main__":
 
    # list of safe methods
    safe_list = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
                 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor',
                 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10',
                 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt',
                 'tan', 'tanh']
 
    # creating a dictionary of safe methods
    safe_dict = dict([(k, locals().get(k, None)) for k in safe_list])
 
    function_creator()

Ahora, si intentamos ejecutar los programas anteriores como:

Enter the function(in terms of x):secret_function()
Enter the value of x:0

Obtenemos la salida:

NameError: name 'secret_function' is not defined

Analicemos el código anterior paso a paso:

  • En primer lugar, creamos una lista de métodos que queremos permitir como lista_segura .
  • A continuación, creamos un diccionario de métodos seguros. En este diccionario, las claves son los nombres de los métodos y los valores son sus espacios de nombres locales.
safe_dict = dict([(k, locals().get(k, None)) 
for k in safe_list])
  • locals() es un método integrado que devuelve un diccionario que asigna todos los métodos y variables en el ámbito local con sus espacios de nombres.
safe_dict['x'] = x

Aquí, también agregamos la variable local x al safe_dict. Ninguna variable local que no sea x será identificada por la función eval .

  • eval acepta diccionarios de variables locales y globales como argumentos. Por lo tanto, para garantizar que ninguno de los métodos integrados esté disponible para evaluar la expresión, también pasamos otro diccionario junto con safe_dict , como se muestra a continuación:
y = eval(expr, {"__builtins__":None}, safe_dict)

¡Entonces, de esta manera, hemos hecho que nuestra función de evaluación esté a salvo de posibles ataques!

Usos de eval

eval no se usa mucho debido a razones de seguridad como exploramos anteriormente.

Aún así, es útil en algunas situaciones como:

  • Es posible que desee usarlo para permitir que los usuarios ingresen sus propios «scriptlets»: expresiones pequeñas (o incluso funciones pequeñas), que se pueden usar para personalizar el comportamiento de un sistema complejo.
  • eval también se usa a veces en aplicaciones que necesitan evaluar expresiones matemáticas. Esto es mucho más fácil que escribir un analizador de expresiones.

Este blog es una contribución de Nikhil Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *