Skip to content

Calling Functions by Name in Python

Updated: at 05:01 AM

In Python, functions are first-class objects that can be assigned to variables, passed as arguments to other functions, and returned from functions. This allows for powerful and flexible coding techniques. One such technique is calling functions by their name, which involves passing the function name as a string and executing the function dynamically.

Calling functions by name can be useful in cases where the function to call is not known ahead of time or needs to be determined dynamically at runtime. It provides a way to implement callbacks, hooks, generic handlers, and flexible command patterns that decouple the caller from the callee.

In this comprehensive guide, you will learn about:

Table of Contents

Open Table of Contents

First-Class Functions in Python

In Python, functions are first-class objects. This means they can be:

For example:

# Assign function to variable
def greet():
  print("Hello!")

greeting = greet

# Pass function as argument
def call_func(func):
  func()

call_func(greet)

# Return function from another function
def make_greeter():
  def greet():
    print("Hello!")
  return greet

greeter = make_greeter()
greeter()

Because functions are regular objects in Python, their names can be programmatically manipulated and accessed as strings. This provides the foundation for calling functions by name.

Calling Functions by Name

In Python, functions can be dynamically called using their name expressed as a string using the following approaches:

1. Built-in globals() Dictionary

The globals() function returns a dictionary representing the current global symbol table. This includes all functions defined at the module level.

A function can be called by passing its name as a string into globals():

def say_hello():
  print("Hello!")

func_name = 'say_hello'
globals()[func_name]() # Calls say_hello()

2. eval() Function

The eval() function evaluates a string as Python code. A function call can be dynamically executed by passing its name in a string to eval():

def add(a, b):
  return a + b

func_call = 'add(1, 2)'
print(eval(func_call)) # Outputs 3

Warning: Using eval() on unsanitized inputs is dangerous and should be avoided!

3. getattr() on Module Objects

Functions defined at the module level can be fetched as attributes on a module object using getattr().

Calling getattr(module, func_name) returns the function, which can then be called:

import math

func_name = 'sqrt'
func = getattr(math, func_name)
print(func(4)) # Prints 2

4. locals() and globals() Dictionaries

Within a function, locals() and globals() can be used together to call functions in the surrounding or global scopes:

def outer():
  x = 1

  def inner():
    func_name = 'print'
    locals()['globals()'][func_name](x) # Calls print(x)

  inner()

outer() # Prints 1

5. __import__() Function

The __import__() function can dynamically import a module and return it.

Functions can then be accessed and called from the imported module:

import math

module_name = 'math'
module = __import__(module_name)

func_name = 'sqrt'
print(getattr(module, func_name)(4)) # Prints 2

Use Cases for Calling Functions by Name

Calling functions by their name string is useful in several cases:

Some concrete examples:

Best Practices

When calling functions by name dynamically, keep these best practices in mind:

Potential Pitfalls

Some potential pitfalls to watch out for when calling functions by name:

Conclusion

Calling functions by name using strings is a powerful technique that enables dynamic and flexible programming when used judiciously. By understanding the different methods available and following best practices, common pitfalls can be avoided.

Used properly, callable references help create generic and extensible interfaces. However, overuse of this technique can lead to confusing and disorganized code. As always, balance flexibility with sensible structure suitable for the situation at hand.