Python has a built-in function that allows you to interpret and execute code (expressions) represented as strings as actual programs. This feature is very powerful and can be used for calculations based on user input or dynamic condition checking. However, because of its power, incorrect usage can lead to serious security vulnerabilities.
This article explains the basic usage of the function to execute strings as code, how to work with variables, and, most importantly, security precautions and alternatives.
Function to Execute Strings as Expressions
Python has a function, eval(), that parses a “string” passed as an argument as a Python “Expression” and executes it.
Syntax:
result = eval("expression_to_execute")
Note: This function can only execute “Expressions” (things that return a value). It cannot execute “Statements” like assignments (a = 10), import statements, or def statements. If you want to execute statements, you would use a different function (like exec), but this article focuses on evaluating expressions.
Specific Example: Dynamic Area Calculation
For example, assume a scenario where a mathematical formula for calculating an area is passed as a string from a configuration file or user input.
# Calculation formula defined as a string
expression = "10 * 20 + 5"
# Evaluate string as a calculation formula
calculated_area = eval(expression)
print(f"Formula: {expression}")
print(f"Result: {calculated_area}")
print(f"Result Type: {type(calculated_area)}")
Output:
Formula: 10 * 20 + 5
Result: 205
Result Type: <class 'int'>
The string "10 * 20 + 5" was interpreted as the Python code 10 * 20 + 5, and the calculation result 205 was returned.
Evaluating Expressions Containing Variables
This function can evaluate expressions by referencing the current scope (variables valid in that location). This allows for dynamic calculations using pre-defined variables.
Specific Example: Calculation Using Parameters
# Variables used for calculation
width = 50
height = 80
offset = 10
# String formula containing variable names
formula = "(width + height) * offset"
# Evaluated using current variable values
result = eval(formula)
print(f"Formula: {formula}")
print(f"Result: {result}")
Output:
Formula: (width + height) * offset
Result: 1300
As shown, even if variable names are included in the string, the values of those variables are referenced at runtime, and the calculation is performed correctly.
[Important] Security Risks and Precautions
This feature allows the execution of “arbitrary code.” This means that if you pass input from outside (user input or communication data) directly to it, there is a risk that malicious code will be executed.
Example of Dangerous Code
Let’s see what happens if a user inputs code to manipulate the system instead of a calculation formula.
Python
import os
# String input by a malicious user (Example)
# Code to display current directory using os module
malicious_input = "__import__('os').getcwd()"
# Execute it
current_dir = eval(malicious_input)
print(f"Current Directory: {current_dir}")
In this example, it only retrieves the current directory, but if it contained a command like __import__('os').system('rm -rf /'), system files could be deleted.
Principle: Never execute input from untrusted sources as is.
Safer Alternative: ast.literal_eval
If you simply want to convert “data in string format (lists, dictionaries, etc.)” into Python objects, you should use literal_eval() from the standard library ast module.
literal_eval() safely evaluates only Python literal structures (strings, numbers, tuples, lists, dictionaries, booleans, None) and does not allow function calls or complex calculations.
import ast
# Dictionary data in string format
data_str = "{'name': 'Tanaka', 'score': 95}"
try:
# Safely convert to dictionary
data_dict = ast.literal_eval(data_str)
print(f"Converted Data: {data_dict}")
print(f"Type: {type(data_dict)}")
# Dangerous code causes an error
# ast.literal_eval("__import__('os')") # ValueError: malformed node or string
except (ValueError, SyntaxError):
print("Failed to convert data.")
Output:
Converted Data: {'name': 'Tanaka', 'score': 95}
Type: <class 'dict'>
Summary
- There is a function (
eval()) that evaluates and executes strings as Python expressions. - It enables calculations within strings and dynamic evaluation using variables.
- It carries extremely high security risks, so avoid using it when handling external input.
- For safe data conversion, use
ast.literal_eval().
