exec() in Python

Exec function can dynamically execute code of python programs. The code can be passed in as string or object code to this function. The object code is executed as is while the string is first parsed and checked for any syntax error. If no syntax error, then the parsed string is executed as a python statement.
exec(object, globals, locals)
Where
Object − A string or a code object passed onto the method.
Object − A string or a code object passed onto the method.
globals − A dictionary of available global methods and variables.
globals − A dictionary of available global methods and variables.
locals − A dictionary of available local methods and variables.
locals − A dictionary of available local methods and variables.
In the below example we pass a single line of code as string to the exec() function. Itr gets parsed and executed to give the output.
x = 9
exec ('print(5*x)')
Running the above code gives us the following result −
45
Now we see how to pass a block of code with multiple code statements. As it is a code object, it gets executed directly giving the result. Please note how we have used \n and space to create a python code block with proper indention.
prog_block = 'x = 3 \nif(x < 5): \n print x*x'
exec(prog_block)
Running the above code gives us the following result −
9
When we do not pass any value for global and local parameter we get the default available functions as per the package imported into the program. In the below example we see the code giving us all the available functions when both global and local parameter values are skipped.
from time import *
exec("print(dir())")
Running the above code gives us the following result −
['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__doc__', '__file__', '__name__', 
'__package__', '_dh', '_exit_code', '_i', '_i1', '_i10', '_i11', '_i12', '_i13', '_i14', '_i15',
 '_i16', '_i17', '_i18', '_i19', '_i2', '_i20', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'clock', 
'copysign', 'cos', 'cosh', 'ctime', 'daylight', 'degrees', 'e', 'erf', 'erfc', 'exit', 'exp', 'expm1', 
'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'get_ipython', 'gmtime', 'hypot', 
'isinf', 'isnan', 'ldexp', 'lgamma', 'localtime', 'log', 'log10', 'log1p', 'mktime', 'modf', 'pi', 
'pow', 'prog', 'prog_block', 'quit', 'radians', 'sin', 'sinh', 'sleep', 'sqrt', 'strftime', 'strptime', 
'struct_time', 'tan', 'tanh', 'time', 'timezone', 'trunc', 'tzname', 'x']
We can restrict the access to any of the functions of the imported module by passing on an empty dictionary as the global parameter. In this case the result will show only the built-in function and it will not show any of the function from the imported module. That is how we restrict and make the function more secure.
 Live Demo
from time import *
exec("print(dir())",{})
Running the above code gives us the following result −
['__builtins__']
Next we see how we can apply only certain chosen functions to the exec() method from the imported module. In the below example we allow only the required function as a parameter with the Global option. The localtime() function is part of the time module which is imported in the program.Example
 Live Demo
from time import *
exec("print lclt()",{"lclt":localtime})
Running the above code gives us the following result −
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=19, tm_hour=12, tm_min=33, tm_sec=53, tm_wday=4, tm_yday=200, tm_isdst=0)
We can also restrict the usage of various functions form the imported modules by using the local parameter and excluding the built in functions completely. In the below example we choose None as the value for built-in global parameter.
 Live Demo
from time import *
exec("print(dir())", {"__builtins__" : None}, {"gtime": gmtime, "print": print, "dir": dir})
Running the above code gives us the following result −
['dir', 'gtime', 'print']