Python’s built-in exec()
function allows you to execute arbitrary Python code from a string or compiled code input.
The exec()
function can be handy when you need to run dynamically generated Python code, but it can be pretty dangerous if you use it carelessly. In this tutorial, you’ll learn not only how to use exec()
, but just as importantly, when it’s okay to use this function in your code.
In this tutorial, you’ll learn how to:
- Work with Python’s built-in
exec()
function - Use
exec()
to execute code that comes as strings or compiled code objects - Assess and minimize the security risks associated with using
exec()
in your code
Additionally, you’ll write a few examples of using exec()
to solve different problems related to dynamic code execution.
To get the most out of this tutorial, you should be familiar with Python’s namespaces and scope, and strings. You should also be familiar with some of Python’s built-in functions.
Sample Code:Click here to download the free sample code that you’ll use to explore use cases for the exec() function.
Getting to Know Python’s exec()
Python’s built-in exec()
function allows you to execute any piece of Python code. With this function, you can execute dynamically generated code. That’s the code that you read, auto-generate, or obtain during your program’s execution. Normally, it’s a string.
The exec()
function takes a piece of code and executes it as your Python interpreter would. Python’s exec()
is like eval()
but even more powerful and prone to security issues. While eval()
can only evaluate expressions, exec()
can execute sequences of statements, as well as imports, function calls and definitions, class definitions and instantiations, and more. Essentially, exec()
can execute an entire fully featured Python program.
The signature of exec()
has the following form:
exec(code[,globals[,locals]])
The function executes code
, which can be either a string containing valid Python code or a compiled code object.
Note: Python is an interpreted language instead of a compiled one. However, when you run some Python code, the interpreter translates it into bytecode, which is an internal representation of a Python program in the CPython implementation. This intermediate translation is also referred to as compiled code and is what Python’s virtual machine executes.
If code
is a string, then it’s parsed as a suite of Python statements, which is then internally compiled into bytecode, and finally executed, unless a syntax error occurs during the parsing or compilation step. If code
holds a compiled code object, then it’s executed directly, making the process a bit more efficient.
The globals
and locals
arguments allow you to provide dictionaries representing the global and local namespaces in which exec()
will run the target code.
The exec()
function’s return value is None
, probably because not every piece of code has a final, unique, and concrete result. It may just have some side effects. This behavior notably differs from eval()
, which returns the result of the evaluated expression.
To get an initial feeling of how exec()
works, you can create a rudimentary Python interpreter with two lines of code:
>>> whileTrue:... exec(input("->> "))...->> print("Hello, World!")Hello, World!->> import thisThe Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex. ...->> x = 10->> if 1 <= x <= 10: print(f"{x} is between 1 and 10")10 is between 1 and 10
In this example, you use an infinite while
loop to mimic the behavior of a Python interpreter or REPL. Inside the loop, you use input()
to get the user’s input at the command line. Then you use exec()
to process and run the input.
This example showcases what’s arguably the main use case of exec()
: executing code that comes to you as a string.
Note: You’ve learned that using exec()
can imply security risks. Now that you’ve seen the main use case of exec()
, what do you think those security risks might be? You’ll find the answer later in this tutorial.
You’ll commonly use exec()
when you need to dynamically run code that comes as a string. For example, you can write a program that generates strings containing valid Python code. You can build these strings from parts that you obtain at different moments in your program’s execution. You can also use the user’s input or any other input source to construct these strings.
Once you’ve built the target code as strings, then you can use exec()
to execute them as you would execute any Python code.
In this situation, you can rarely be certain of what your strings will contain. That’s one reason why exec()
implies serious security risks. This is particularly true if you’re using untrusted input sources, like a user’s direct input, in building your code.
Read the full article at https://realpython.com/python-exec/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]