Functions groups statements that perform a certain  task. The statements within a function are only executed when the function is called.

Normally, calling a function involves typing  the function name followed by parentheses () and any necessary arguments.

# the function definition
def add(a, b):
    '''a function to add two numbers'''
    print(f'{a} + {b} = {a + b}')

#Call the function
add(10, 20)

In the above example, we defined the function add then called it using its name followed by the parenthesis and the the two arguments to be added inside the parenthesis.

We may however want to call the function when we have its name as a string, this may especially be the case when  the name of the function is determined at runtime. We will look at two approaches that this can be achieved:

  • Using eval() and exec() functions
  • Using the getattr() function 

Using eval() and exec() functions

using the eval() function

The builtin eval() function is used to  evaluate a single expression, it returns the value yielded by the evaluated expression.  This  function can be used with any valid expression including functions calls. We can use it with  a function's name to execute the function from a string identifier.

#the function
def add(a, b):
   return f"{a} + {b} = {a + b}"

#call the function using a string
result = eval('add')(20, 40)

print(result)

In the above example, we defined the function add()​​​​​​, then called it using its name as a string. You should note that:

  • The eval() function evaluates the name 'add' based on the programs context.
  • It looks for the name in the local and global variables and returns the object that is associated with it.
  • In the above case, the object is a function and thus a function object is returned.
  • We can perform all valid function operations with the object such as calling it using parenthesis and passing any necessary argument.​

We can also alteratively,  pass the function's name together with the calling constructs, in which case eval() will return the function's return value rather than the function itself

#the function
def add(a, b):
   return f"{a} + {b} = {a + b}"

#call the function using a string
result = eval('add(20, 40)')

print(result)

In the above case we passed  a string containing the function's name together with the parenthesis and the arguments. The result is that the  eval() function evaluates the entire function call and returns the function's return value.

Using the exec() function

As we have seen above, the eval() function evaluates a single expression and returns the yielded value. The exec() function, on the other hand, executes arbitrary Python code given as a string not just a single expression.

Unlike the eval() function, the exec() function does not return any value , it instead returns None. This makes it suitable only when the target function does not return any value because otherwise, the returned value will be lost .

#a function that does not return any value
def prod(a, b):
   print(f"{a} x {b} = {a * b}")

#call the function as a string using exec()
exec('prod(2, 4)')

Using the getattr() function 

The builtin getattr() function is used to dynamically retrieve an object attributes such as methods and variables. When being called , the class object and the name of the attribute  are passed as the arguments. The function returns the actual object associated with the given name.

The getattr() function works primarily on objects, this makes it only applicable when the function we are dealing with is attached to an object in form of a method.

class Evaluator:
    def add(a, b):
        print(f'{a} + {b} = {a + b}')

    def prod(a, b):
        print(f'{a} x {b} = {a * b}')


getattr(Evaluator, 'add')(3, 4)
getattr(Evaluator, 'prod')(3, 4)

The following example shows how we can use the getattr() function to call functions from a module. 

# import module 
import math 

# call function from module using getattr 

square = getattr(math, 'pow')(2, 2) 
print(square)

In the above snippet, we have used the getattr() function to call the pow() function from the math module.