Online Tutorials & Training Materials | STechies.com
Register Login

What Does Python eval() Function Do?

20 Nov 2019 1:01 pm || 0

While coding in Python, you might have used the Python console or command line to execute a piece of code directly. You can write some code without compiling it into a separate program. String concatenation or mathematical operations can be done easily this way. But, there may be a case when you might have to run some code within the program. This can be done using an eval() method offered by Python.

What is eval() in Python?

It is a built-in function. In layman language, the eval() method runs the python code (which is passed as an argument) within the program.

OR

The eval() method parses the expression passed to it and runs python expression(code) within the program.

Syntax

eval(expression, globals, locals)

Parameters

  • expression (Required): String as passed and evaluated as Python code
  • globals (Optional):  a dictionary containing global parameters
  • locals (Optional): a dictionary containing local parameters
  • Return: Returns the result of the evaluated expression

Example:

# Simple program to explain eval () method

x = 12
y = 20

print(eval('x+y'))

Explanation

Here, the eval() method is used to run the code as it is written inside the brackets. Thus, the value of x and y are added and printed to the screen.

eval() Function with User Input

The best way to use eval() function is executing user input while doing dynamic execution of statements.

Here is a complex example where we have asked the user to enter the function to execute.

Example:

# eval() with user input
from math import *

func = input("Enter Function to Evaluate:\n")
try:
    print(eval(func))
except Exception as ex:
    print(ex)

Output:

Enter Math Function to Evaluate:
pow(2,3)
8.0

Explanation

The first line of the program imports all the methods in the math module. Then the input() method is used for obtaining the name of the function to execute from the user. The name of the function is stored in the func variable.

Then a try statement is used for printing out the result of the eval(func) method. Here, the function specified by the user is executed by the eval() method. If an exception is raised, it is printed by the print() method.

As per the output, the user has entered the function pow(2,3) for evaluation. So, the method finds out the value of the number 2 raised to the power of 3. The final output will be 8.

Vulnerabilities With eval() Function

As we know eval() function is used to execute in-built Python function with the user input. 

Suppose we have os module imported and the user enters os.system('rm -rf /') command to execute.

Once the command gets executed, it will start to delete system files and corrupt our environment.

That’s why you must check the user entered data first, before using the eval() function to execute user input code. This can be very useful whenever you use globals and locals parameters. 

eval() Function with Global and Local Directory

With the help of global and local directory, we can restrict the user to execute a limited set to commands.

The code below checks the available functions and variables in the local and global scope.

Example:

# Python program to check local and global scope

# Import math library 
from math import *;

def power(n,m):
    return pow(n,m)

print(globals()) #This will return the current global symbol table.
print(locals())  #This will return the current local symbol table.
print(dir())  #List of the names in current local scope 

Output:

{'atan2': <built-in function atan2>, 'gamma': <built-in function gamma>, 'fabs': <built-in function fabs>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7fa14f913e10>, 'log': <built-in function log>, 'log1p': <built-in function log1p>, 'sin': <built-in function sin>, 'copysign': <built-in function copysign>, '__name__': '__main__', 'factorial': <built-in function factorial>, 'log10': <built-in function log10>, 'lgamma': <built-in function lgamma>, 'degrees': <built-in function degrees>, 'sinh': <built-in function sinh>, 'cosh': <built-in function cosh>, 'acosh': <built-in function acosh>, 'ldexp': <built-in function ldexp>, '__file__': 'main.py', 'hypot': <built-in function hypot>, 'pi': 3.141592653589793, '__doc__': None, 'e': 2.718281828459045, 'pow': <built-in function pow>, 'frexp': <built-in function frexp>, 'fmod': <built-in function fmod>, 'trunc': <built-in function trunc>, 'asinh': <built-in function asinh>, 'erfc': <built-in function erfc>, 'acos': <built-in function acos>, 'expm1': <built-in function expm1>, '__spec__': None, 'erf': <built-in function erf>, 'radians': <built-in function radians>, 'isinf': <built-in function isinf>, 'ceil': <built-in function ceil>, '__builtins__': <module 'builtins' (built-in)>, 'fsum': <built-in function fsum>, 'tanh': <built-in function tanh>, 'log2': <built-in function log2>, 'tan': <built-in function tan>, 'cos': <built-in function cos>, 'power': <function power at 0x7fa14f962bf8>, 'atanh': <built-in function atanh>, 'asin': <built-in function asin>, 'floor': <built-in function floor>, 'modf': <built-in function modf>, 'atan': <built-in function atan>, 'isnan': <built-in function isnan>, 'sqrt': <built-in function sqrt>, '__package__': None, 'isfinite': <built-in function isfinite>, '__cached__': None, 'exp': <built-in function exp>}
{'atan2': <built-in function atan2>, 'gamma': <built-in function gamma>, 'fabs': <built-in function fabs>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7fa14f913e10>, 'log': <built-in function log>, 'log1p': <built-in function log1p>, 'sin': <built-in function sin>, 'copysign': <built-in function copysign>, '__name__': '__main__', 'factorial': <built-in function factorial>, 'log10': <built-in function log10>, 'lgamma': <built-in function lgamma>, 'degrees': <built-in function degrees>, 'sinh': <built-in function sinh>, 'cosh': <built-in function cosh>, 'acosh': <built-in function acosh>, 'ldexp': <built-in function ldexp>, '__file__': 'main.py', 'hypot': <built-in function hypot>, 'pi': 3.141592653589793, '__doc__': None, 'e': 2.718281828459045, 'pow': <built-in function pow>, 'frexp': <built-in function frexp>, 'fmod': <built-in function fmod>, 'trunc': <built-in function trunc>, 'asinh': <built-in function asinh>, 'erfc': <built-in function erfc>, 'acos': <built-in function acos>, 'expm1': <built-in function expm1>, '__spec__': None, 'erf': <built-in function erf>, 'radians': <built-in function radians>, 'isinf': <built-in function isinf>, 'ceil': <built-in function ceil>, '__builtins__': <module 'builtins' (built-in)>, 'fsum': <built-in function fsum>, 'tanh': <built-in function tanh>, 'log2': <built-in function log2>, 'tan': <built-in function tan>, 'cos': <built-in function cos>, 'power': <function power at 0x7fa14f962bf8>, 'atanh': <built-in function atanh>, 'asin': <built-in function asin>, 'floor': <built-in function floor>, 'modf': <built-in function modf>, 'atan': <built-in function atan>, 'isnan': <built-in function isnan>, 'sqrt': <built-in function sqrt>, '__package__': None, 'isfinite': <built-in function isfinite>, '__cached__': None, 'exp': <built-in function exp>}
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'power', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

Explanation

In the above example, you can see that eval() function has access to lots of functions. To access all these functions that are built-in, we have imported the math library. All the functions are from the math library.

In the program written above, all the methods within the math module are imported using the * operator. Then a function called power is defined using the def keyword. This function takes two parameters, n and m. The functions returns the result of the pow(n,m) where the value of n raised to the power m will be calculated.

The next print statement prints out the result of calling the globals() function. This returns a dictionary that has all the variables in the global namespace. The next print() method displays the variables of the local namespace. The last print statement displays the result of the dir() method. This function is used to returns all the names of the current local scope. The dir() returns all the attributes and methods of an object.     

eval() Function with Empty Directory

Code: 

print(eval('dir()',{})) 

Output:

['__builtins__']

You can see if we run eval() function with empty directory still it has the access to builtin methods. 

So to restrict the user to use the limited function, you need to specify this function as global.

Example:

# Python eval() function with global

# Import math library
from math import *;

# Take input from user 
userInput = input("Enter Math Function to Evaluate.\nAllowed Functions are \nsamllIntegral(n)\nlargestIntegral(n)\nabs(n)\nfact(n)\n");

try:
    print(eval(userInput,{'samllIntegral':ceil,'largestIntegral':floor,'abs':fabs,'fact':factorial}))
except Exception as excep:
    print(excep)

print('Operation Done')

Output:

Enter Math Function to Evaluate. 
Allowed Functions are 
samllIntegral(n) 
largestIntegral(n) 
abs(n) 
fact(n) 
samllIntegral(2.3) 
3 
Operation Done

Explanation

In the above example, we have restricted the user to run only limited programs like “ceil, floor, fabs” if the user enters in any other function then program will raise an exception. 

In the first line, all the methods are imported from the math module. The input() method is used for obtaining the function to evaluate, from the user. This value is stored in the userInput method. The allowed functions are smallIntegral(n), largestIntegral(n), abs(n) and fact(n). Then, inside the try block, the print statement is used for returning the value of calling the eval() method. All the functions are assigned a value within the dictionary 
{'samllIntegral':ceil,'largestIntegral':floor,'abs':fabs,'fact':factorial}. If the user tries to execute any other method, an exception is raised. This will be caught by the except statement and printed to the screen using the print() method.

After the execution of the function according to the user’s choice, a print statement prints the string “Operation done”.

Example with Local Scope

# Python eval() function with local

# Import math library

userInput1 = int(input("Enter first value to Evaluate : "))
userInput2 = int(input("Enter first value to Evaluate : "))

try:
    print(eval('input_1 + input_2',{'__builtins__':None},{'input_1':userInput1,'input_2':userInput2}))
except Exception as excep:
    print(excep)

print('Operation Done')

Output:

Enter first value to Evaluate : 21
Enter first value to Evaluate : 21
42
Operation Done

Explanation

The first two lines are used for obtaining two values from the user using the input() method. The values are converted to an integer using the int() method. The two integers are stored in variables userInput1 and userInput2 respectively. Then a try and except block is executed that prints the result of the eval() method.

The eval() method takes three arguments. They are - ('input_1 + input_2',{'__builtins__':None},{'input_1':userInput1,'input_2':userInput2}. This statement evaluates the summation of the two numbers entered by the user. The except statement handles any exception that may be raised by the try block during program execution. This exception will be printed to the screen.

The last print statement prints “Operation done”.

Conclusion

The details of the eval() method have been discussed. The eval() method is a very useful method for allowing the users to enter their own small programs and parse them instantly. Apart from writing code for parser programs, the eval() method can be used for executing small mathematical functions.