Python exec ()

El método exec () ejecuta el programa creado dinámicamente, que es una cadena o un objeto de código.

La sintaxis de exec():

 exec (objeto, globales, locales)

Parámetros exec ()

exec() toma tres parámetros:

  • objeto : una cadena o un objeto de código
  • globals (opcional) - un diccionario
  • locales (opcional): un objeto de mapeo. El diccionario es el tipo de mapeo estándar y comúnmente utilizado en Python.

El uso de globales y locales se discutirá más adelante en el artículo.

Valor de retorno de exec ()

exec()no devuelve ningún valor, devuelve None.

Ejemplo 1: ¿Cómo funciona exec ()?

 program = 'a = 5b=10print("Sum =", a+b)' exec(program)

Salida

 Suma = 15

Aquí, se pasa el programa objeto de cadena al exec()que se ejecuta el programa. En este caso, se omiten los globales y los locales.

Ejemplo 2: permitir que el usuario proporcione información

  program = input('Enter a program:') exec(program) 

Salida

 Ingrese un programa: (imprimir (elemento) para el elemento en (1, 2, 3)) 1 2 3

Si desea tomar el código Python del usuario que permite el código multilínea (usando ''), puede usar el compile()método antes de usarlo exec().

Obtenga más información sobre el método compile () en Python.

Tenga cuidado al usar exec ()

Considere una situación, está utilizando un sistema Unix (macOS, Linux, etc.) y ha importado un osmódulo. El módulo del sistema operativo proporciona una forma portátil de utilizar las funciones del sistema operativo, como leer o escribir un archivo.

Si permite que los usuarios ingresen un valor usando exec(input()), el usuario puede emitir comandos para cambiar el archivo o incluso eliminar todos los archivos usando el comando os.system('rm -rf *').

Si está utilizando exec(input())en su código, es una buena idea comprobar qué variables y métodos puede utilizar el usuario. Puede ver qué variables y métodos están disponibles usando el método dir ().

 from math import * exec('print(dir())')

Salida

('In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__name__', '_dh', '_i', '_i1', '_i2', ' _ih ',' _ii ',' _iii ',' _oh ',' _sh ',' acos ',' acosh ',' asin ',' asinh ',' atan ',' atan2 ',' atanh ',' ceil ' , 'copysign', 'cos', 'cosh', 'grados', 'e', ​​'erf', 'erfc', 'salida', 'exp', 'expm1', 'fabs', 'factorial', ' piso ',' fmod ',' frexp ',' fsum ',' gamma ',' gcd ',' get_ipython ',' hypot ',' inf ',' isclose ',' isfinite ',' isinf ',' isnan ' , 'ldexp', 'lgamma ',' log ',' log10 ',' log1p ',' log2 ',' modf ',' nan ',' pi ',' pow ',' quit ',' radianes ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')

Restringir el uso de métodos y variables disponibles en exec ()

La mayoría de las veces, todos los métodos y variables disponibles que se utilizan en exec()pueden no ser necesarios, o incluso pueden tener un agujero de seguridad. Puede restringir el uso de estas variables y métodos pasando parámetros globales y locales opcionales (diccionarios) al exec()método.

1. Se omiten los parámetros globales y locales.

Si se omiten ambos parámetros (como en nuestros ejemplos anteriores), el código que se espera que ejecute exec()se ejecuta en el ámbito actual. Puede verificar las variables y métodos disponibles usando el siguiente código:

 exec ('imprimir (dir ())')

2. Paso de parámetro global; se omite el parámetro locals

Los parámetros globales y locales (diccionarios) se utilizan para variables globales y locales, respectivamente. Si se omite el diccionario local, el valor predeterminado es diccionario global. Es decir, se utilizarán globales tanto para variables globales como locales.

Nota: Puede consultar el diccionario actual global y local en Python utilizando los métodos integrados globals () y locals () respectivamente.

3. Pasar diccionario vacío como parámetro global

 from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())

Si pasa un diccionario vacío como globales, solo __builtins__están disponibles para el object(primer parámetro del exec ()). A pesar de que hemos importado el módulo matemático en el programa anterior, intentar acceder a cualquiera de las funciones proporcionadas por el módulo matemático generará una excepción.

Salida

 ('__builtins__')

Hacer que ciertos métodos estén disponibles

 from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))

Aquí, el código que ejecuta exec () también puede tener métodos sqrt()y pow()junto con __builtins__.

Es posible cambiar el nombre del método según su deseo.

 from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))

En el programa anterior, squareRoot()calcula la raíz cuadrada (funcionalidad similar a sqrt()). Sin embargo, intentar usarlo sqrt()generará una excepción.

Restringir el uso de elementos integrados

Puede restringir el uso de __builtins__dando valor Nonea '__builtins__'en el diccionario global.

 exec (objeto, ('__builtins__': Ninguno)) 

4. Pasar el diccionario local y global

Puede hacer que las funciones y variables necesarias estén disponibles para su uso pasando el diccionario local. Por ejemplo:

 from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)

Salida

 ('dir', 'imprimir') 

Aquí, solo dos métodos integrados print () y dir () pueden ejecutarse por exec()método.

Es importante tener en cuenta que exec()ejecuta el código y no devuelve ningún valor (devuelve None). Por lo tanto, no puede usar declaraciones de retorno y rendimiento fuera de las definiciones de función.

Articulos interesantes...