La función Eval intenta ejecutar e interpretar la cadena (argumento) que se le pasa como código python. x = 1 print (eval ('x + 1')) La salida del código anterior será 2. La desventaja de este enfoque es que el usuario obtiene independencia de la escritura del código, lo que puede generar condiciones de caos. accediendo a muchas variables y métodos pasando parámetros globales y locales en la función eval.
ATIF IBAD KHAN
Respuestas:
276
La función eval permite que un programa Python ejecute código Python dentro de sí mismo.
jaja, ese fue un ejemplo trivial, pero puedes dejar que el usuario escriba un comando arbitrario y que Python lo ejecute. Entonces, puede hacer que el usuario escriba una cadena de comando y luego hacer que Python lo ejecute como código. Entonces, por ejemplo: eval ("__ import __ ('os'). Remove ('file')").
BYS2
6060
Parecerá inútil hasta que encuentre una necesidad para ello. Se utiliza en sitios como codepad.org para permitirle ejecutar scripts en un entorno de prueba. eval()también se puede usar para ejecutar código altamente dinámico, pero debe tener plena conciencia de los riesgos de seguridad y rendimiento antes de usarlo.
George Cummins
66
@GeorgeCummins, codepad.org no usa eval, ni podría hacer lo que hace eval.
Mike Graham
16
@GeorgeCummins: codepag.org ejecuta todo en una caja de arena: una cárcel chroot con controles de trazas en una máquina virtual para evitar que el código malicioso haga algo malo. Mucho más complicado que una simple evaluación. Además, eval es específico de Python. el teclado es compatible con varios idiomas.
FogleBird
44
@GeorgeCummins, codepad ejecuta un sistema muy complejo para ejecutar de forma segura programas arbitrarios. eval, además de ser inseguro, no puede ejecutar programas completos como lo hace el teclado porque solo puede evaluar una sola expresión.
Mike Graham
165
eval()interpreta una cadena como código. La razón por la que tanta gente le ha advertido sobre el uso de esto es porque un usuario puede usar esto como una opción para ejecutar código en la computadora. Si tiene eval(input())e osimportó, una persona podría escribir input()os.system('rm -R *')y eliminar todos sus archivos en su directorio de inicio. (Suponiendo que tiene un sistema unix). Usar eval()es un agujero de seguridad. Si necesita convertir cadenas a otros formatos, intente usar cosas que hagan eso, como int().
Quieres decir que usar evalcon input()es un agujero de seguridad. No ponga input()dentro de una declaración eval y estará bien.
Rohmer
19
@Rohmer, los datos inseguros pueden provenir de todas partes: solicitudes web, campos de entrada de formulario, lecturas de archivos, ... no solo de la entrada de la consola. Incluso si escribe los archivos usted mismo, puede contener entradas que originalmente provienen de una fuente no confiable. Entonces, evales un problema de seguridad en muchos casos.
sanderd17
3
ya que inputgeneralmente toma sus datos de la consola, el usuario podría simplemente salir del programa y escribir de rm -R *todos modos ...
cz
63
Muchas buenas respuestas aquí, pero ninguna describe el uso de eval()en el contexto de its globalsy localskwargs, es decir eval(expression, globals=None, locals=None)(ver documentos evalaquí ).
Se pueden usar para limitar las funciones que están disponibles a través de la evalfunción. Por ejemplo, si carga un nuevo intérprete de Python, el locals()y globals()será el mismo y se verá así:
Ciertamente, hay funciones dentro del builtinsmódulo que pueden causar un daño significativo a un sistema. Pero es posible bloquear cualquier cosa y todo lo que no queremos disponible. Pongamos un ejemplo. Digamos que queremos construir una lista para representar un dominio de los núcleos disponibles en un sistema. Para mí tengo 8 núcleos, así que querría una lista [1, 8].
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')[1,8]
Del mismo modo, todo __builtins__está disponible.
>>>eval('abs(-1)')1
Okay. Entonces, allí vemos una función que queremos exponer y un ejemplo de un método (de muchos que pueden ser mucho más complejos) que no queremos exponer. Así que bloqueemos todo.
Hemos bloqueado efectivamente todas las __builtins__funciones y, como tal, hemos traído un nivel de protección a nuestro sistema. En este punto, podemos comenzar a agregar nuevamente las funciones que queremos exponer.
Ahora tenemos la cpu_countfunción disponible mientras bloqueamos todo lo que no queremos. En mi opinión, esto es súper poderoso y claramente desde el alcance de las otras respuestas, no es una implementación común. Hay numerosos usos para algo como esto y siempre que se maneje correctamente, personalmente creo que se evalpuede usar de manera segura con gran valor.
nótese bien
Otra cosa que es genial acerca de esto kwargses que puede comenzar a usar la taquigrafía para su código. Digamos que usa eval como parte de una tubería para ejecutar texto importado. El texto no necesita tener un código exacto, puede seguir algún formato de archivo de plantilla y aún ejecutar lo que desee. Por ejemplo:
>>>from os import cpu_count
>>>eval('[1,cores]',{'__builtins__':None},{'cores': cpu_count()})[1,8]
En Python 2.x input(...)es equivalente a eval(raw_input(...)), en Python 3.x raw_inputse renombró input, lo que sospecho conduce a su confusión (probablemente estaba buscando la documentación inputen Python 2.x). Además, eval(input(...))funcionaría bien en Python 3.x, pero aumentaría a TypeErroren Python 2.
En este caso evalse utiliza para obligar a la cadena devuelta de inputuna expresión e interpretada. En general, esto se considera una mala práctica.
¿Por qué debería escribirlo entre comillas? Input obtiene una cadena y la pasa a eval, no ejecuta el código, por lo que estaría bien si simplemente escribiera 1 + 1 ... ¿?
JC Rocamonde
El caso es que estás mezclando P2.xy 3.x. En Python 2 su código funciona, pero no tiene sentido evaluar dos veces. En python 3 no lo hace, y devuelve una cadena.
JC Rocamonde
6
eval()evalúa la cadena pasada como una expresión de Python y devuelve el resultado. Por ejemplo, eval("1 + 1")interpreta y ejecuta la expresión "1 + 1"y devuelve el resultado (2).
Una razón por la que puede confundirse es porque el código que citó implica un nivel de indirección. La llamada a la función interna (entrada) se ejecuta primero para que el usuario vea el mensaje "bla". Imaginemos que responden con "1 + 1" (citas agregadas para mayor claridad, no las escriba al ejecutar su programa), la función de entrada devuelve esa cadena, que luego se pasa a la función externa (eval) que interpreta la cadena y devuelve el resultado (2).
eval(), como su nombre indica, evalúa el argumento pasado.
raw_input()ahora está input()en versiones de python 3.x. Entonces, el ejemplo más común para el uso de eval()es su uso para proporcionar la funcionalidad que input()proporciona la versión 2.x de python. raw_input devolvió los datos ingresados por el usuario como una cadena, mientras que input evaluó el valor de los datos ingresados y los devolvió.
eval(input("bla bla"))replica la funcionalidad de input()in 2.x, es decir, de evaluar los datos ingresados por el usuario.
En resumen: eval()evalúa los argumentos que se le pasan y, por lo tanto, eval('1 + 1')devuelve 2.
Una de las aplicaciones útiles de eval()es evaluar las expresiones de python desde cadenas. Por ejemplo, cargar desde la representación de cadena de archivo del diccionario:
Otra opción si desea limitar la cadena de evaluación a literales simples es usar ast.literal_eval(). Algunos ejemplos:
import ast
# print(ast.literal_eval('')) # SyntaxError: unexpected EOF while parsing# print(ast.literal_eval('a')) # ValueError: malformed node or string# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax# print(ast.literal_eval('1+1')) # 2: but only works due to a quirk in parser# print(ast.literal_eval('1*1')) # ValueError: malformed node or stringprint(ast.literal_eval("{'a':1}"))# {'a':1}
Evalúe de forma segura un nodo de expresión o una cadena que contenga un literal de Python o una pantalla de contenedor. La cadena o nodo proporcionado solo puede consistir en las siguientes estructuras literales de Python: cadenas, bytes, números, tuplas, listas, dictos, conjuntos, booleanos y Ninguno.
Esto se puede usar para evaluar de forma segura las cadenas que contienen valores de Python de fuentes no confiables sin la necesidad de analizar los valores uno mismo. Es no capaz de evaluar expresiones arbitrariamente complejas, por ejemplo, la participación de los operadores o indexación.
Permitir expresiones de operador con literales es posible, pero mucho más complejo que la implementación actual. Una implementación simple no es segura: puede inducir el uso básicamente ilimitado de CPU y memoria sin esfuerzo (intente "9 ** 9 ** 9" o "[Ninguno] * 9 ** 9").
En cuanto a la utilidad, esta función es útil para "volver a leer" valores literales y contenedores en cadena por repr (). Esto se puede usar, por ejemplo, para la serialización en un formato similar pero más potente que JSON.
ast.literal_evalno es compatible con operadores, contrario a su '1+1'ejemplo. No obstante, admite listas, números, cadenas, etc., por lo que es una buena alternativa para evalcasos de uso comunes .
Respuestas:
La función eval permite que un programa Python ejecute código Python dentro de sí mismo.
Ejemplo de eval (shell interactivo):
fuente
eval()
también se puede usar para ejecutar código altamente dinámico, pero debe tener plena conciencia de los riesgos de seguridad y rendimiento antes de usarlo.eval
, ni podría hacer lo que haceeval
.eval
, además de ser inseguro, no puede ejecutar programas completos como lo hace el teclado porque solo puede evaluar una sola expresión.eval()
interpreta una cadena como código. La razón por la que tanta gente le ha advertido sobre el uso de esto es porque un usuario puede usar esto como una opción para ejecutar código en la computadora. Si tieneeval(input())
eos
importó, una persona podría escribirinput()
os.system('rm -R *')
y eliminar todos sus archivos en su directorio de inicio. (Suponiendo que tiene un sistema unix). Usareval()
es un agujero de seguridad. Si necesita convertir cadenas a otros formatos, intente usar cosas que hagan eso, comoint()
.fuente
eval
coninput()
es un agujero de seguridad. No pongainput()
dentro de una declaración eval y estará bien.eval
es un problema de seguridad en muchos casos.input
generalmente toma sus datos de la consola, el usuario podría simplemente salir del programa y escribir derm -R *
todos modos ...Muchas buenas respuestas aquí, pero ninguna describe el uso de
eval()
en el contexto de itsglobals
ylocals
kwargs, es decireval(expression, globals=None, locals=None)
(ver documentoseval
aquí ).Se pueden usar para limitar las funciones que están disponibles a través de la
eval
función. Por ejemplo, si carga un nuevo intérprete de Python, ellocals()
yglobals()
será el mismo y se verá así:Ciertamente, hay funciones dentro del
builtins
módulo que pueden causar un daño significativo a un sistema. Pero es posible bloquear cualquier cosa y todo lo que no queremos disponible. Pongamos un ejemplo. Digamos que queremos construir una lista para representar un dominio de los núcleos disponibles en un sistema. Para mí tengo 8 núcleos, así que querría una lista[1, 8]
.Del mismo modo, todo
__builtins__
está disponible.Okay. Entonces, allí vemos una función que queremos exponer y un ejemplo de un método (de muchos que pueden ser mucho más complejos) que no queremos exponer. Así que bloqueemos todo.
Hemos bloqueado efectivamente todas las
__builtins__
funciones y, como tal, hemos traído un nivel de protección a nuestro sistema. En este punto, podemos comenzar a agregar nuevamente las funciones que queremos exponer.Ahora tenemos la
cpu_count
función disponible mientras bloqueamos todo lo que no queremos. En mi opinión, esto es súper poderoso y claramente desde el alcance de las otras respuestas, no es una implementación común. Hay numerosos usos para algo como esto y siempre que se maneje correctamente, personalmente creo que seeval
puede usar de manera segura con gran valor.nótese bien
Otra cosa que es genial acerca de esto
kwargs
es que puede comenzar a usar la taquigrafía para su código. Digamos que usa eval como parte de una tubería para ejecutar texto importado. El texto no necesita tener un código exacto, puede seguir algún formato de archivo de plantilla y aún ejecutar lo que desee. Por ejemplo:fuente
En Python 2.x
input(...)
es equivalente aeval(raw_input(...))
, en Python 3.xraw_input
se renombróinput
, lo que sospecho conduce a su confusión (probablemente estaba buscando la documentacióninput
en Python 2.x). Además,eval(input(...))
funcionaría bien en Python 3.x, pero aumentaría aTypeError
en Python 2.En este caso
eval
se utiliza para obligar a la cadena devuelta deinput
una expresión e interpretada. En general, esto se considera una mala práctica.fuente
input
significa lo queraw_input
hizo en 2.x.Tal vez un ejemplo engañoso de leer una línea e interpretarla.
Prueba
eval(input())
y escribe"1+1"
: esto debería imprimirse2
. Eval evalúa expresiones.fuente
eval()
evalúa la cadena pasada como una expresión de Python y devuelve el resultado. Por ejemplo,eval("1 + 1")
interpreta y ejecuta la expresión"1 + 1"
y devuelve el resultado (2).Una razón por la que puede confundirse es porque el código que citó implica un nivel de indirección. La llamada a la función interna (entrada) se ejecuta primero para que el usuario vea el mensaje "bla". Imaginemos que responden con "1 + 1" (citas agregadas para mayor claridad, no las escriba al ejecutar su programa), la función de entrada devuelve esa cadena, que luego se pasa a la función externa (eval) que interpreta la cadena y devuelve el resultado (2).
Lea más sobre eval aquí .
fuente
eval()
, como su nombre indica, evalúa el argumento pasado.raw_input()
ahora estáinput()
en versiones de python 3.x. Entonces, el ejemplo más común para el uso deeval()
es su uso para proporcionar la funcionalidad queinput()
proporciona la versión 2.x de python. raw_input devolvió los datos ingresados por el usuario como una cadena, mientras que input evaluó el valor de los datos ingresados y los devolvió.eval(input("bla bla"))
replica la funcionalidad deinput()
in 2.x, es decir, de evaluar los datos ingresados por el usuario.En resumen:
eval()
evalúa los argumentos que se le pasan y, por lo tanto,eval('1 + 1')
devuelve 2.fuente
Una de las aplicaciones útiles de
eval()
es evaluar las expresiones de python desde cadenas. Por ejemplo, cargar desde la representación de cadena de archivo del diccionario:Léalo como una variable y edítelo:
Salida:
fuente
eval
hace?Llego tarde a responder esta pregunta, pero nadie parece dar una respuesta clara a la pregunta.
Si un usuario ingresa un valor numérico,
input()
devolverá una cadena.Por lo tanto,
eval()
evaluará el valor devuelto (o expresión) que es una cadena y devolverá entero / flotante.Por supuesto, esta es una mala práctica.
int()
ofloat()
debe usarse en lugar deeval()
en este caso.fuente
Otra opción si desea limitar la cadena de evaluación a literales simples es usar
ast.literal_eval()
. Algunos ejemplos:De los documentos :
En cuanto a por qué es tan limitado, de la lista de correo :
fuente
ast.literal_eval
no es compatible con operadores, contrario a su'1+1'
ejemplo. No obstante, admite listas, números, cadenas, etc., por lo que es una buena alternativa paraeval
casos de uso comunes .