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 os
mó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 None
a '__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.