¿Uso de eval en Python?

Hay una función eval() en Python con la que tropecé mientras jugaba. No puedo pensar en un caso cuando esta función es necesaria, excepto tal vez como azúcar sintáctica. ¿Alguien puede dar un ejemplo?

Related of "¿Uso de eval en Python?"

eval y exec son una forma rápida y sucia de obtener un código fuente dinámicamente, tal vez munge un poco y luego ejecutarlo, pero casi nunca son la mejor manera, especialmente en código de producción en lugar de “quick- and-dirty “prototipos & c.

Por ejemplo, si tuviera que lidiar con fonts dinámicas de Python, ast.literal_eval módulo ast – ast.literal_eval es MUCHO más seguro que eval (puede llamarlo directamente en una forma de cadena de la expresión, si es una -off y se basa únicamente en constantes simples, o hacer node = ast.parse(source) primero, luego mantener el node alrededor, tal vez munge con visitantes adecuados, por ejemplo, para búsqueda de variables, luego literal_eval el nodo) – o, una vez que haya puesto el nodo en forma adecuada y lo examinó por cuestiones de seguridad, podría compile (generando un objeto de código) y construir un nuevo objeto de función a partir de eso. Mucho menos simple (¡excepto que ast.literal_eval es tan simple como eval para los casos más simples!) Pero más seguro y preferible en código de calidad de producción.

Para muchas tareas que he visto (ab-) usar exec y eval , los potentes incorporaciones de Python, como getattr y setattr , indexación en globals() , & c, proporcionan soluciones preferibles y, de hecho, a menudo más simples. Para usos específicos como el análisis de JSON, los módulos de la biblioteca como json son mejores (por ejemplo, consulte el comentario de SilentGhost sobre la respuesta del tinnitus a esta pregunta). Etcétera etcétera…

El artículo de Wikipedia sobre eval es bastante informativo y detalla varios usos.

Algunos de los usos que sugiere son:

  • Evaluando expresiones matematicas
  • Comstackción bootstrapping
  • Scripting (los lenguajes dynamics en general son muy adecuados para esto)
  • Tutores de idiomas

Es posible que desee utilizarlo para permitir que los usuarios ingresen sus propios “scriptlets”: pequeñas expresiones (o incluso pequeñas funciones), que se pueden usar para personalizar el comportamiento de un sistema complejo .
En ese contexto, y si no tiene que preocuparse demasiado por las implicaciones de seguridad (por ejemplo, tiene una base de usuarios informada), entonces eval () puede ser una buena opción.

En el pasado, he usado eval () para agregar una interfaz de depuración a mi aplicación. Creé un servicio de telnet que lo dejó en el entorno de la aplicación en ejecución. Las entradas se ejecutaron a través de eval () para que pueda ejecutar de forma interactiva los comandos de Python en la aplicación.

En un progtwig que escribí una vez, tenía un archivo de entrada donde podía especificar parámetros geométricos como valores y como expresiones de python de los valores anteriores, por ejemplo:

 a=10.0 b=5.0 c=math.log10(a/b) 

Un analizador de Python leyó este archivo de entrada y obtuvo los datos finales evaluando los valores y las expresiones usando eval ().

No digo que sea una buena progtwigción, pero no tuve que conducir un reactor nuclear.

Lo uso como un rápido analizador JSON …

 r=''' { "glossary": { "title": "example glossary" } } ''' print eval(r)['glossary']['title'] 

eval() normalmente no es muy útil. Una de las pocas cosas para las que lo he usado (bueno, era exec() realidad, pero es bastante similar) fue permitir al usuario escribir una aplicación que escribí en Python. Si estuviera escrito en algo como C ++, tendría que incrustar un intérprete de Python en la aplicación.

Eval es una forma de interactuar con el intérprete de Python desde un progtwig. Puedes pasar los literales a eval y los evalúa como expresiones de python.

Por ejemplo –

 print eval("__import__('os').getcwd()") 

Devolvería el directorio de trabajo actual.

aclamaciones

Puedes usar eval en un decorador:

 #this replaces the original printNumber with a lambda-function, #which takes no arguments and which calls the old function with #the number 10 @eval("lambda fun: lambda: fun(10)") def printNumber(i: int) -> None: print("The number is %i", i) #call printNumber() 

mientras que no puedes usar expresiones complejas como

 @lambda fun: lambda: fun(10) def ... 

ni

 @(lambda fun: lambda: fun(10)) def ... 

No puede usar una expresión lambda allí, porque el decorador debe ser un identificador:

 @myModule.functionWithOneArg 

o una llamada de función:

 @functionReturningFunctionWithOneArg(any, "args") 

Verá que la llamada de la función eval con una cadena tiene una syntax válida aquí, pero la expresión lambda no. (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions )

Lo utilicé para ingresar valores variables al progtwig principal:

test.py var1 = 2 var2 = True

 var1=0 var2=False for arg in sys.argv[1:]: exec(arg) 

Una forma burda de permitir args de palabras clave en el progtwig principal. Si hay una mejor manera, házmelo saber!

eval () es para una sola oración, mientras que exec () es para varias.

Por lo general, los usamos para agregar o visitar algunos scripts como bash shell.

Debido a que pueden ejecutar algunas secuencias de comandos de bytes en la memoria, si tiene algunos datos importantes o secuencias de comandos puede decodificar y descomprimir su ‘secreto’ y luego hacer todo lo que quiera.

Acabo de encontrar un buen uso de eval. Estaba escribiendo un conjunto de pruebas para algún código, y creé una clase de prueba, donde cada método era una prueba que debía ejecutarse. Quería una forma de poder ejecutar todos los métodos de prueba sin tener que llamar a cada método individualmente. Entonces, escribí algo bastante sucio.

 class Test: def __init__(self, *args): #bs def test1(self): #bs def test2(self): #bs if __name__ == "__main__": import argparse #argparse bs test = Test(*bs_args) for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__): print(eval('test.{func}()'.format(func = func))) 

La evaluación dinámica de casos de prueba arbitrarios es bastante buena. Solo tengo que escribir el método, y después de guardar puedo incluir el método en mi conjunto de pruebas. En cuanto al código, básicamente solo inspecciono los métodos definidos en el objeto de prueba y me aseguro de que no sean métodos o atributos “mágicos” de Python predeterminados para el objeto de prueba. Después de eso puedo asumir que son métodos y pueden ser evaluados.

Uso exec para crear un sistema de complementos en Python.

     tratar:
         exec ("from" + plugin_name + "import Plugin")
         myplugin = Plugin (module_options, config = config)
     excepto ImportError, mensaje:
         fatal ("No hay tal módulo" + plugin_name + \
                "(o ningún constructor de Plugin) en mi ruta de Python:" + str (mensaje))
     excepto excepción:
         fatal ("Module" + plugin_name + "no se puede cargar:" + \
                str (sys.exc_type) + ":" + str (sys.exc_value) + \
                ". \ n ¿Puede ser una opción perdida o errónea?")

Con un plugin como:

 Plugin de clase:

     def __init__ (self):
         pasar

     consulta de def (self, arg):
          ...

Podrás llamarlo como:

     resultado = myplugin.query ("algo")

No creo que puedas tener complementos en Python sin exec / eval .