Pregunta ¿Qué hace la evaluación de Python ()?


En el libro que estoy leyendo en Python, sigue usando el código eval(input('blah')) 

Leí la documentación y la entiendo, pero todavía no veo cómo cambia la input() función.

¿Qué hace? ¿Alguien puede explicar?


186
2018-02-21 19:19


origen


Respuestas:


La función eval permite que un programa Python ejecute código Python dentro de sí mismo.

Ejemplo de eval (shell interactivo):

>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1

183
2018-02-21 19:20



eval() interpreta una cadena como código. La razón por la cual muchas personas lo han 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 usted tiene eval(input()) y os importado, una persona podría escribir input()  os.system('rm -R *') que eliminaría todos tus archivos en tu directorio personal. (Suponiendo que tienes un sistema Unix). Utilizando eval() es un agujero de seguridad Si necesita convertir cadenas a otros formatos, intente usar cosas que hagan eso, como int().


114
2018-02-21 19:39



En Python 2.x input(...) es equivalente a eval(raw_input(...)), en Python 3.x raw_input fue renombrado input, que sospecho conducen a su confusión (probablemente estaba mirando la documentación de input en Python 2.x). Adicionalmente, eval(input(...)) funcionaría bien en Python 3.x, pero generaría TypeError en Python 2.

En este caso eval se utiliza para forzar la cadena devuelta desde input en una expresión e interpretada. En general, esto se considera una mala práctica.


26
2018-02-21 19:21



Hay muchas buenas respuestas aquí, pero ninguna describe el uso de eval en el contexto de su globals= y locals= kwargs. Estos pueden usarse para limitar los métodos que están disponibles a través del eval método. Por ejemplo, si carga un nuevo intérprete de Python, locals() y globals() será el mismo y se verá algo como esto:

>>> globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
 '__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
 '__package__': None, '__name__': '__main__'}

Ciertamente hay métodos dentro del builtins módulo que puede causar un daño significativo a un sistema. Pero es posible bloquear todo y todo lo que no queremos disponible. Tomemos 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 me gustaría una lista [1, 8].

>>>from os import cpu_count()
>>>eval('[1, cpu_count()'])
[1, 8]

Del mismo modo todos __builtins__ está disponible.

>>>eval('abs(-1)')
1

De acuerdo. Entonces, vemos un método que queremos exponer y un ejemplo de uno (de muchos que pueden ser mucho más insidiosos) método que no queremos exponer. Entonces bloqueemos todo.

>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable

Hemos bloqueado efectivamente todas las __builtins__ métodos y como tal trajo un nivel de protección en nuestro sistema. En este punto, podemos comenzar a agregar nuevamente en los métodos que queremos expuestos.

>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable

Ahora tenemos el método cpu_count disponible mientras aún 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. Existen numerosos usos para algo como esto y siempre que se maneje correctamente, personalmente siento eval se puede usar de forma segura con gran valor.

nótese bien 

Algo más que es genial acerca de estos kwargs es que puedes comenzar a usar la abreviatura de tu código. Supongamos que usa eval como parte de una canalización para ejecutar algún texto importado. El texto no necesita tener un código exacto, puede seguir un formato de archivo de plantilla y aún ejecutar cualquier cosa que desee. Por ejemplo:

>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]

15
2018-04-27 20:22



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 estar confundido es porque el código que citó implica un nivel de indirección. La llamada de función interna (entrada) se ejecuta primero para que el usuario vea el aviso "blah". Imaginemos que responden con "1 + 1" (las comillas se añaden 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).

Leer más sobre eval aquí.


6
2018-02-21 19:30



eval(), como su nombre lo sugiere, evalúa el argumento pasado.

raw_input() es ahora input() en versiones Python 3.x. Entonces, el ejemplo más comúnmente encontrado para el uso de eval() es su uso para proporcionar la funcionalidad que input() proporcionado en la versión 2.x de python. raw_input devolvió los datos ingresados ​​por el usuario como una cadena, mientras que la entrada evaluó el valor de los datos ingresados ​​y los devolvió.

eval(input("bla bla")) así replica la funcionalidad de input() en 2.x, es decir, de evaluación de los datos ingresados ​​por el usuario.

En breve: eval() evalúa los argumentos que se le pasan y, por lo tanto, eval('1 + 1') regresó 2.


5
2018-06-23 21:54



Tal vez un ejemplo engañoso de leer una línea e interpretarla.

Tratar eval(input()) y tipo "1+1" - esto debería imprimir 2. Eval evalúa expresiones.


4
2018-02-21 19:27



Una de las aplicaciones útiles de eval() es evaluar expresiones de pitón de una cadena. Por ejemplo, carga de la representación de cadenas de archivos del diccionario:

running_params = {"Greeting":"Hello "}

fout = open("params.dat",'w')

fout.write(repr(running_params))

fout.close()

Léelo como una variable y edítelo:

fin = open("params.dat",'r')

diction=eval(fin.read())

diction["Greeting"]+="world"

fin.close()

print diction

Salida:

{'Greeting': 'Hello world'}

4
2018-03-27 19:10



Llegué tarde para 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.

>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'

Asi que, eval() evaluará el valor devuelto (o expresión) que es una cadena y devuelve entero / flotante.

>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>> 
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14

Por supuesto, esta es una mala práctica. int() o float() debe ser utilizado en lugar de eval() en este caso.

>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14

2
2018-06-13 04:59