The short answer, or TL;DR

Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.

eval and exec have these two differences:

  1. eval accepts only a single expression, exec can take a code block that has Python statements: loops, try: except:, class and function/method definitions and so on.

    An expression in Python is whatever you can have as the value in a variable assignment:

    Copya_variable = (anything you can put within these parentheses is an expression)
    
  2. eval returns the value of the given expression, whereas exec ignores the return value from its code, and always returns None (in Python 2 it is a statement and cannot be used as an expression, so it really does not return anything).

In versions 1.0 - 2.7, exec was a statement, because CPython needed to produce a different kind of code object for functions that used exec for its side effects inside the function.

In Python 3, exec is a function; its use has no effect on the compiled bytecode of the function where it is used.


Thus basically:

Copy>>> a = 5
>>> eval('37 + a')   # it is an expression
42
>>> exec('37 + a')   # it is an expression statement; value is ignored (None is returned)
>>> exec('a = 47')   # modify a global variable as a side effect
>>> a
47
>>> eval('a = 47')  # you cannot evaluate a statement
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    a = 47
      ^
SyntaxError: invalid syntax

The compile in 'exec' mode compiles any number of statements into a bytecode that implicitly always returns None, whereas in 'eval' mode it compiles a single expression into bytecode that returns the value of that expression.

Copy>>> eval(compile('42', '<string>', 'exec'))  # code returns None
>>> eval(compile('42', '<string>', 'eval'))  # code returns 42
42
>>> exec(compile('42', '<string>', 'eval'))  # code returns 42,
>>>                                          # but ignored by exec

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

Copy>>> compile('for i in range(3): print(i)', '<string>', 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

Actually the statement "eval accepts only a single expression" applies only when a string (which contains Python source code) is passed to eval. Then it is internally compiled to bytecode using compile(source, '<string>', 'eval') This is where the difference really comes from.

If a code object (which contains Python bytecode) is passed to exec or eval, they behave identically, excepting for the fact that exec ignores the return value, still returning None always. So it is possible use eval to execute something that has statements, if you just compiled it into bytecode before instead of passing it as a string:

Copy>>> eval(compile('if 1: print("Hello")', '<string>', 'exec'))
Hello
>>>

works without problems, even though the compiled code contains statements. It still returns None, because that is the return value of the code object returned from compile.

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

Copy>>> compile('for i in range(3): print(i)', '<string>'. 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

The longer answer, a.k.a the gory details

exec and eval

The exec function (which was a statement in Python 2) is used for executing a dynamically created statement or program:

Copy>>> program = '''
for i in range(3):
    print("Python is cool")
'''
>>> exec(program)
Python is cool
Python is cool
Python is cool
>>> 

The eval function does the same for a single expression, and returns the value of the expression:

Copy>>> a = 2
>>> my_calculation = '42 * a'
>>> result = eval(my_calculation)
>>> result
84

exec and eval both accept the program/expression to be run either as a str, unicode or bytes object containing source code, or as a code object which contains Python bytecode.

If a str/unicode/bytes containing source code was passed to exec, it behaves equivalently to:

Copyexec(compile(source, '<string>', 'exec'))

and eval similarly behaves equivalent to:

Copyeval(compile(source, '<string>', 'eval'))

Since all expressions can be used as statements in Python (these are called the Expr nodes in the Python abstract grammar; the opposite is not true), you can always use exec if you do not need the return value. That is to say, you can use either eval('my_func(42)') or exec('my_func(42)'), the difference being that eval returns the value returned by my_func, and exec discards it:

Copy>>> def my_func(arg):
...     print("Called with %d" % arg)
...     return arg * 2
... 
>>> exec('my_func(42)')
Called with 42
>>> eval('my_func(42)')
Called with 42
84
>>> 

Of the 2, only exec accepts source code that contains statements, like def, for, while, import, or class, the assignment statement (a.k.a a = 42), or entire programs:

Copy>>> exec('for i in range(3): print(i)')
0
1
2
>>> eval('for i in range(3): print(i)')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

Both exec and eval accept 2 additional positional arguments - globals and locals - which are the global and local variable scopes that the code sees. These default to the globals() and locals() within the scope that called exec or eval, but any dictionary can be used for globals and any mapping for locals (including dict of course). These can be used not only to restrict/modify the variables that the code sees, but are often also used for capturing the variables that the executed code creates:

Copy>>> g = dict()
>>> l = dict()
>>> exec('global a; a, b = 123, 42', g, l)
>>> g['a']
123
>>> l
{'b': 42}

(If you display the value of the entire g, it would be much longer, because exec and eval add the built-ins module as __builtins__ to the globals automatically if it is missing).

In Python 2, the official syntax for the exec statement is actually exec code in globals, locals, as in

Copy>>> exec 'global a; a, b = 123, 42' in g, l

However the alternate syntax exec(code, globals, locals) has always been accepted too (see below).

compile

The compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) built-in can be used to speed up repeated invocations of the same code with exec or eval by compiling the source into a code object beforehand. The mode parameter controls the kind of code fragment the compile function accepts and the kind of bytecode it produces. The choices are 'eval', 'exec' and 'single':

  • 'eval' mode expects a single expression, and will produce bytecode that when run will return the value of that expression:

    Copy>>> dis.dis(compile('a + b', '<string>', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 RETURN_VALUE
    
  • 'exec' accepts any kinds of python constructs from single expressions to whole modules of code, and executes them as if they were module top-level statements. The code object returns None:

    Copy>>> dis.dis(compile('a + b', '<string>', 'exec'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 POP_TOP                             <- discard result
                  8 LOAD_CONST               0 (None)   <- load None on stack
                 11 RETURN_VALUE                        <- return top of stack
    
  • 'single' is a limited form of 'exec' which accepts a source code containing a single statement (or multiple statements separated by ;) if the last statement is an expression statement, the resulting bytecode also prints the repr of the value of that expression to the standard output(!).

    An if-elif-else chain, a loop with else, and try with its except, else and finally blocks is considered a single statement.

    A source fragment containing 2 top-level statements is an error for the 'single', except in Python 2 there is a bug that sometimes allows multiple toplevel statements in the code; only the first is compiled; the rest are ignored:

    In Python 2.7.8:

    Copy>>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    >>> a
    5
    

    And in Python 3.4.2:

Answer from Antti Haapala on Stack Overflow
🌐
Quora
quora.com › Whats-the-difference-between-exec-and-eval-in-Python
What's the difference between exec() and eval() in Python? - Quora
Eval takes a single expression as input, evaluates the expression according to Python rules, and returns the resulting value. Eval also lets you provide additional input in order to lock down which functions are allowed to be called.
Top answer
1 of 3
751

The short answer, or TL;DR

Basically, eval is used to evaluate a single dynamically generated Python expression, and exec is used to execute dynamically generated Python code only for its side effects.

eval and exec have these two differences:

  1. eval accepts only a single expression, exec can take a code block that has Python statements: loops, try: except:, class and function/method definitions and so on.

    An expression in Python is whatever you can have as the value in a variable assignment:

    Copya_variable = (anything you can put within these parentheses is an expression)
    
  2. eval returns the value of the given expression, whereas exec ignores the return value from its code, and always returns None (in Python 2 it is a statement and cannot be used as an expression, so it really does not return anything).

In versions 1.0 - 2.7, exec was a statement, because CPython needed to produce a different kind of code object for functions that used exec for its side effects inside the function.

In Python 3, exec is a function; its use has no effect on the compiled bytecode of the function where it is used.


Thus basically:

Copy>>> a = 5
>>> eval('37 + a')   # it is an expression
42
>>> exec('37 + a')   # it is an expression statement; value is ignored (None is returned)
>>> exec('a = 47')   # modify a global variable as a side effect
>>> a
47
>>> eval('a = 47')  # you cannot evaluate a statement
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    a = 47
      ^
SyntaxError: invalid syntax

The compile in 'exec' mode compiles any number of statements into a bytecode that implicitly always returns None, whereas in 'eval' mode it compiles a single expression into bytecode that returns the value of that expression.

Copy>>> eval(compile('42', '<string>', 'exec'))  # code returns None
>>> eval(compile('42', '<string>', 'eval'))  # code returns 42
42
>>> exec(compile('42', '<string>', 'eval'))  # code returns 42,
>>>                                          # but ignored by exec

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

Copy>>> compile('for i in range(3): print(i)', '<string>', 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

Actually the statement "eval accepts only a single expression" applies only when a string (which contains Python source code) is passed to eval. Then it is internally compiled to bytecode using compile(source, '<string>', 'eval') This is where the difference really comes from.

If a code object (which contains Python bytecode) is passed to exec or eval, they behave identically, excepting for the fact that exec ignores the return value, still returning None always. So it is possible use eval to execute something that has statements, if you just compiled it into bytecode before instead of passing it as a string:

Copy>>> eval(compile('if 1: print("Hello")', '<string>', 'exec'))
Hello
>>>

works without problems, even though the compiled code contains statements. It still returns None, because that is the return value of the code object returned from compile.

In the 'eval' mode (and thus with the eval function if a string is passed in), the compile raises an exception if the source code contains statements or anything else beyond a single expression:

Copy>>> compile('for i in range(3): print(i)', '<string>'. 'eval')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

The longer answer, a.k.a the gory details

exec and eval

The exec function (which was a statement in Python 2) is used for executing a dynamically created statement or program:

Copy>>> program = '''
for i in range(3):
    print("Python is cool")
'''
>>> exec(program)
Python is cool
Python is cool
Python is cool
>>> 

The eval function does the same for a single expression, and returns the value of the expression:

Copy>>> a = 2
>>> my_calculation = '42 * a'
>>> result = eval(my_calculation)
>>> result
84

exec and eval both accept the program/expression to be run either as a str, unicode or bytes object containing source code, or as a code object which contains Python bytecode.

If a str/unicode/bytes containing source code was passed to exec, it behaves equivalently to:

Copyexec(compile(source, '<string>', 'exec'))

and eval similarly behaves equivalent to:

Copyeval(compile(source, '<string>', 'eval'))

Since all expressions can be used as statements in Python (these are called the Expr nodes in the Python abstract grammar; the opposite is not true), you can always use exec if you do not need the return value. That is to say, you can use either eval('my_func(42)') or exec('my_func(42)'), the difference being that eval returns the value returned by my_func, and exec discards it:

Copy>>> def my_func(arg):
...     print("Called with %d" % arg)
...     return arg * 2
... 
>>> exec('my_func(42)')
Called with 42
>>> eval('my_func(42)')
Called with 42
84
>>> 

Of the 2, only exec accepts source code that contains statements, like def, for, while, import, or class, the assignment statement (a.k.a a = 42), or entire programs:

Copy>>> exec('for i in range(3): print(i)')
0
1
2
>>> eval('for i in range(3): print(i)')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    for i in range(3): print(i)
      ^
SyntaxError: invalid syntax

Both exec and eval accept 2 additional positional arguments - globals and locals - which are the global and local variable scopes that the code sees. These default to the globals() and locals() within the scope that called exec or eval, but any dictionary can be used for globals and any mapping for locals (including dict of course). These can be used not only to restrict/modify the variables that the code sees, but are often also used for capturing the variables that the executed code creates:

Copy>>> g = dict()
>>> l = dict()
>>> exec('global a; a, b = 123, 42', g, l)
>>> g['a']
123
>>> l
{'b': 42}

(If you display the value of the entire g, it would be much longer, because exec and eval add the built-ins module as __builtins__ to the globals automatically if it is missing).

In Python 2, the official syntax for the exec statement is actually exec code in globals, locals, as in

Copy>>> exec 'global a; a, b = 123, 42' in g, l

However the alternate syntax exec(code, globals, locals) has always been accepted too (see below).

compile

The compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) built-in can be used to speed up repeated invocations of the same code with exec or eval by compiling the source into a code object beforehand. The mode parameter controls the kind of code fragment the compile function accepts and the kind of bytecode it produces. The choices are 'eval', 'exec' and 'single':

  • 'eval' mode expects a single expression, and will produce bytecode that when run will return the value of that expression:

    Copy>>> dis.dis(compile('a + b', '<string>', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 RETURN_VALUE
    
  • 'exec' accepts any kinds of python constructs from single expressions to whole modules of code, and executes them as if they were module top-level statements. The code object returns None:

    Copy>>> dis.dis(compile('a + b', '<string>', 'exec'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_NAME                1 (b)
                  6 BINARY_ADD
                  7 POP_TOP                             <- discard result
                  8 LOAD_CONST               0 (None)   <- load None on stack
                 11 RETURN_VALUE                        <- return top of stack
    
  • 'single' is a limited form of 'exec' which accepts a source code containing a single statement (or multiple statements separated by ;) if the last statement is an expression statement, the resulting bytecode also prints the repr of the value of that expression to the standard output(!).

    An if-elif-else chain, a loop with else, and try with its except, else and finally blocks is considered a single statement.

    A source fragment containing 2 top-level statements is an error for the 'single', except in Python 2 there is a bug that sometimes allows multiple toplevel statements in the code; only the first is compiled; the rest are ignored:

    In Python 2.7.8:

    Copy>>> exec(compile('a = 5\na = 6', '<string>', 'single'))
    >>> a
    5
    

    And in Python 3.4.2:

2 of 3
219
  1. exec is not an expression: a statement in Python 2.x, and a function in Python 3.x. It compiles and immediately evaluates a statement or set of statement contained in a string. Example:

    Copy exec('print(5)')           # prints 5.
     # exec 'print 5'     if you use Python 2.x, nor the exec neither the print is a function there
     exec('print(5)\nprint(6)')  # prints 5{newline}6.
     exec('if True: print(6)')  # prints 6.
     exec('5')                 # does nothing and returns nothing.
    
  2. eval is a built-in function (not a statement), which evaluates an expression and returns the value that expression produces. Example:

    Copy x = eval('5')              # x <- 5
     x = eval('%d + 6' % x)     # x <- 11
     x = eval('abs(%d)' % -100) # x <- 100
     x = eval('x = 5')          # INVALID; assignment is not an expression.
     x = eval('if 1: x = 4')    # INVALID; if is a statement, not an expression.
    
  3. compile is a lower level version of exec and eval. It does not execute or evaluate your statements or expressions, but returns a code object that can do it. The modes are as follows:

  4. compile(string, '', 'eval') returns the code object that would have been executed had you done eval(string). Note that you cannot use statements in this mode; only a (single) expression is valid.

  5. compile(string, '', 'exec') returns the code object that would have been executed had you done exec(string). You can use any number of statements here.

  6. compile(string, '', 'single') is like the exec mode but expects exactly one expression/statement, eg compile('a=1 if 1 else 3', 'myf', mode='single')

Discussions

More similarity between exec() and eval() - Ideas - Discussions on Python.org
I propose that the only differences between these two builtins should be: If the first argument is a string, then it is compiled as a file input for exec() or an expression for eval(). exec() returns None, and eval() returns the evaluation of the source code/string. More on discuss.python.org
🌐 discuss.python.org
0
December 7, 2022
Why is exec() and eval() not considered good practice?
exec and eval basically execute the code AS IF you wrote it. Maybe if you're the one using it would be OK, but on public facing applications then you have the risk of code injection. Someone crafting a string that will do something completely different. It is bad practice just for that, and you can make it work with other approaches. On your case, there are easier ways of finding something by its "name". You can set up a dict of objects (IE AllItems). Whose key is your "nameOfWeapon" identifier. And do AllItems[nameOfWeapon] to get it. And after getting it you can call the method you have on it. More on reddit.com
🌐 r/learnpython
27
50
July 27, 2024
When to use compile and exec/eval?
i rarely have to use them. one example was i needed to import settings based on a passed-in string, so i did something like d = {}; exec('import config_{} as local_config'.format(env), d). when you do this with exec, you scope where the execution happens so you don't clobber any global variables. generally though, you almost never need them, and when you think you do, you usually don't. http://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile-in-python exceptional cases might be like More on reddit.com
🌐 r/learnpython
8
4
December 15, 2016
Why is it advised to not use exec?
If you're thinking about using exec, there are two likely scenarios: 1 - you want to execute some code from a string 2 - you want to let users execute code from an input string In option 1, you are already in control of your code, and there are smarter / saner ways of controlling the code flow / logic than using exec. In option 2, there are security concerns because the user can input bad code and brick their system (or your server, if it's an web app). Consider for example: s = input("write your code:") result = exec(s) print(result) If the user inputs import shutil; shutil.rmtree("/"), say goodbye to your filesystem. More on reddit.com
🌐 r/learnpython
23
23
June 5, 2022
🌐
Real Python
realpython.com › python-eval-function
Python eval(): Evaluate Expressions Dynamically – Real Python
October 21, 2023 - In the next three sections, you’ll learn what these arguments are and how eval() uses them to evaluate Python expressions on the fly. Note: You can also use exec() to dynamically execute Python code.
🌐
Python.org
discuss.python.org › ideas
More similarity between exec() and eval() - Ideas - Discussions on Python.org
December 7, 2022 - I propose that the only differences ... a file input for exec() or an expression for eval(). exec() returns None, and eval() returns the evaluation of the source code/string....
🌐
Reddit
reddit.com › r/learnpython › why is exec() and eval() not considered good practice?
r/learnpython on Reddit: Why is exec() and eval() not considered good practice?
July 27, 2024 -

Fairly new to coding and I am making a simple dungeon crawler with Python for a school project.

Since it will include a range of weapons which are objects, I'm currently using

thing = eval(nameOfWeapon + ".get_itemStat()")

(where nameOfWeapon is a variable so I can use this code for any item the player wants to access)

and things similar to that. This feels the most straightforward to me out of my own knowledge, but all sources online consider this a bad practice.

Is there a reason for this or alternatives that are considered better practice? This project will be getting graded so I don't want to lose marks if it's considered a python cardinal sin or something.

🌐
Medium
medium.com › @brusooo27 › python-exec-vs-eval-ea949931ee8f
Python exec vs eval | Medium
July 26, 2023 - Python provides two powerful built-in functions, eval and exec, eval function in Python evaluates an expression represented as a string. The exec function executes a sequence of statements represented as a string or code object.
🌐
Medium
medium.com › @codingpilot25 › difference-between-eval-and-exec-in-python-b387b25207d2
Difference between eval() and exec() in python | by Keerti Prajapati | Medium
May 16, 2021 - Eval() only evaluates the single expression, not the complex logic code, whereas Exec can be used to execute any number of expression.
Find elsewhere
🌐
Armin Ronacher
lucumr.pocoo.org › 2011 › 2 › 1 › exec-in-python
Be careful with exec and eval in Python | Armin Ronacher's Thoughts and Writings
February 1, 2011 - $ python -mtimeit -s 'code = "a = 2; b = 3; c = a * b"' 'exec code' 10000 loops, best of 3: 22.7 usec per loop $ python -mtimeit -s 'code = compile("a = 2; b = 3; c = a * b", "<string>", "exec")' 'exec code' 1000000 loops, best of 3: 0.765 usec per loop · 32 times as fast for a very short code example. It becomes a lot worse the more code you have. Why is that the case? Because parsing Python code and converting that into Bytecode is an expensive operation compared to evaluating the bytecode.
🌐
Medium
medium.com › @techclaw › python-eval-vs-exec-understanding-the-key-differences-f88d6ab85c0d
Python eval() vs. exec(): Understanding the Key Differences | by TechClaw | Medium
September 28, 2023 - On the other hand, exec() is another built-in function in Python that is used to execute a block of Python code. It takes a string as an argument, compiles the code, and then executes it. Unlike eval(), exec() doesn’t return any value.
🌐
Linux Hint
linuxhint.com › use-eval-and-exec-functions-in-python
How to Use Eval and Exec Functions in Python – Linux Hint
The exec function works similar to the eval function with some differences. The expression supplied to the exec function can be a string or any other valid Python object that contains valid Python code. In comparison, the eval function only takes string expressions.
🌐
O'Reilly
oreilly.com › library › view › python-essential-reference › 0672328623 › 0672328623_ch06lev1sec13.html
Python: Essential Reference, Third Edition
February 20, 2006 - For example: ... Similarly, the exec statement executes a string containing arbitrary Python code. The code supplied to exec is executed as if the code actually appeared in place of the exec statement.
Author   David Beazley
Published   2006
Pages   648
🌐
Geek Python
geekpython.in › exec-and-eval
Difference between exec() and eval() with Examples
August 3, 2024 - The exec() function doesn't return any value whereas the eval() function returns a value computed from the expression.
🌐
CodeSpeedy
codespeedy.com › home › difference between eval() and exec() functions in python
Difference between Eval() and Exec() functions in Python - CodeSpeedy
January 4, 2020 - This function used to execute the complex Python code dynamically, unlike the eval() function can only execute a single expression.
🌐
Codingdeeply
codingdeeply.com › home › python eval vs exec: understanding the key differences
Python eval vs exec: Understanding the Key Differences
February 23, 2024 - We will discuss these considerations in more detail in later sections of this article. Python exec is a built-in function in Python that is used to execute a block of dynamically created code.
🌐
Edureka Community
edureka.co › home › community › categories › python › what s the difference between eval exec and...
What s the difference between eval exec and compile in Python | Edureka Community
August 28, 2018 - I've been looking at dynamic evaluation of Python code, and come across the eval() and compile() ... and how the different modes of compile() fit in?
🌐
YouTube
youtube.com › watch
Exec() VS Eval() Explained In Python Tutorial 2023 - YouTube
What is the difference between exec() and eval() in Python, and how can we use them in our scripts? Well I'm here to teach you all of that today!▶ Become job...
Published   May 22, 2023
🌐
Sololearn
sololearn.com › en › Discuss › 1019733 › execeval-difference
exec/eval difference | Sololearn: Learn to code for FREE!
Sololearn is the world's largest community of people learning to code. With over 25 programming courses, choose from thousands of topics to learn how to code, brush up your programming knowledge, upskill your technical ability, or stay informed about the latest trends.
🌐
Python Morsels
pythonmorsels.com › dynamically-evaluating-code
Dynamically evaluating code - Python Morsels
December 12, 2022 - The eval function accepts a single expression and returns the result of that expression. The exec function runs a whole block of Python code.
🌐
Javatpoint
javatpoint.com › python-eval-vs-exec
Python eval() vs. exec() - Javatpoint
Python eval() vs. exec() with Codes in Python with tutorial, tkinter, button, overview, canvas, frame, environment set-up, first python program, etc.
🌐
Plain English
python.plainenglish.io › the-dark-side-of-python-why-eval-and-exec-are-security-nightmares-36b9406dc140
The dark side of Python: Why eval() and exec() are security nightmares | by Roman Huliak | Python in Plain English
June 16, 2025 - Before we dive into why these functions are so dangerous, let’s understand what they do. The eval() function evaluates a string as a Python expression and returns the result, while exec() executes a string as Python code without returning a value.