Learn how to dynamically call Python functions from a module using their names as strings, enabling flexible and powerful programming techniques.
In Python, functions are first-class objects, meaning they can be manipulated like any other data type. This includes the ability to call functions dynamically using their names stored as strings. This technique is particularly useful when you don't know which specific function you need to execute until runtime.
Let's explore how to call Python functions dynamically using their names stored as strings.
Understanding the Goal
Imagine you have a situation where you don't know the exact function to call until your program is running. You might have the function's name stored in a variable, read from a file, or received as user input. This is where calling functions by their string names becomes essential.
Methods
Using getattr()
import my_module
function_name = "my_function"
my_function = getattr(my_module, function_name)result = my_function() Using globals() or locals()
Ideal for: Functions defined in the same scope where you're calling from.
Retrieve the function from the global or local symbol table:
def greet(name):
return f"Hello, {name}!"
function_name = "greet"
my_function = globals()[function_name]
# Or: my_function = locals()[function_name] Call the function:
result = my_function("Alice") Important Considerations
eval() to call functions from strings. If the string content comes from an untrusted source (like user input), it could lead to serious security vulnerabilities.Example
def add(x, y):
return x + y
def subtract(x, y):
return x - y
operation = input("Enter operation ('add' or 'subtract'): ")
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
if operation in ["add", "subtract"]:
selected_function = globals()[operation]
result = selected_function(num1, num2)
print(f"Result: {result}")
else:
print("Invalid operation!")In this example, the user's input determines which function (add or subtract) is called.
This Python code defines three functions: add, subtract, and greet. It then prompts the user to choose one of these functions by name. Based on the user's input, the code dynamically calls the chosen function with user-provided arguments and displays the result. The code includes input validation to ensure the user enters a valid function name and, for the arithmetic functions, numeric input.
def add(x, y):
"""Adds two numbers."""
return x + y
def subtract(x, y):
"""Subtracts two numbers."""
return x - y
def greet(name):
"""Greets the person passed in as a parameter."""
return f"Hello, {name}!"
# Store function names in a list
functions = ["add", "subtract", "greet"]
# Get user input for function name
while True:
function_name = input(f"Enter a function name ({', '.join(functions)}): ")
if function_name in functions:
break
else:
print("Invalid function name. Please try again.")
# Call the function dynamically
if function_name == "greet":
name = input("Enter a name: ")
result = globals()[function_name](name)
else:
try:
num1 = float(input("Enter the first number: "))
num2 = float(input("Enter the second number: "))
result = globals()[function_name](num1, num2)
except ValueError:
print("Invalid input. Please enter numbers only.")
result = None
# Print the result
if result is not None:
print(f"Result: {result}")Explanation:
add, subtract, and greet.functions stores the valid function names for user selection.globals()[function_name] expression retrieves the function object from the global namespace using the string stored in function_name.add/subtract, a name for greet).try-except block handles potential ValueError exceptions if the user enters non-numeric input for add or subtract.Key Points:
On getattr():
getattr() isn't limited to functions. You can use it to retrieve any attribute of an object (methods, variables) by its name.getattr() calls to access attributes within nested objects. For example: getattr(getattr(my_object, 'nested_object'), 'attribute_name')
On globals() and locals():
globals() accesses global variables, while locals() accesses variables in the current local scope.Security and Best Practices:
Additional Techniques:
eval() (Use with Extreme Caution): While powerful, eval() is generally discouraged for dynamic function calling due to its security risks. If you must use it, ensure the input is completely trusted and sanitized.inspect Module: The inspect module provides advanced tools for introspection, including ways to get information about functions and call them dynamically.When to Use Dynamic Function Calling:
Remember: Dynamic function calling can make your code more concise and adaptable, but it also introduces complexity and potential security risks. Use it judiciously and prioritize security and maintainability.
This table summarizes how to call Python functions dynamically using their names stored as strings:
| Method | Ideal For | How it Works | Security Considerations |
|---|---|---|---|
getattr() |
Functions within modules and classes | - Get a reference to the function using its name and the module/class it belongs to. - Call the retrieved function. | Generally safe when used with known modules and classes. |
globals()/locals()
|
Functions defined in the same scope | - Retrieve the function from the global or local symbol table using its name as a key. - Call the retrieved function. | Be cautious when using with user-provided input as it can lead to security risks. |
eval() |
Not Recommended | Executes a string as Python code. Highly discouraged due to severe security risks. | Avoid using eval() for dynamically calling functions from strings, especially with untrusted input. |
Key Points:
eval().Dynamic function calling in Python, where functions are called using their names stored as strings, offers flexibility in scenarios where the specific function to execute is unknown until runtime. Techniques like using getattr(), globals(), and locals() enable this capability. However, it's crucial to prioritize security, especially when handling user input, as misuse can lead to vulnerabilities. While eval() exists, it's strongly discouraged due to its high security risks. Alternatives like dictionaries or design patterns offer safer and more structured approaches. Choosing the appropriate method depends on factors like the function's location (module, class, or scope) and the source of the function name. Always sanitize user input rigorously and consider whitelisting allowed function names to mitigate risks. By understanding the methods, security implications, and best practices, developers can leverage dynamic function calling effectively while maintaining a secure and robust codebase.
Call a function by a String name - Python - GeeksforGeeks | A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
Here is how to call a function of a module by using its name in Python | To call a function of a module by using its name in Python, you can use the getattr function. Alternatively, you can also use the globals() function to retrieve ...
Python: How to dynamically call a method/function given a string of ... | Python: How to dynamically call a method/function given a string of its name - python-call-method-from-string.py
inspect — Inspect live objects — Python 3.12.7 documentation | Source code: Lib/inspect.py The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, ...
Call a Function by a String name in Python | by Glasshost | Medium | Sometimes, we may need to call a function in Python whose name is only known during runtime or whose name is stored in a string. In such cases, we can use the getattr() function to call the…
ctypes — A foreign function library for Python — Python 3.12.7 ... | Source code: Lib/ctypes ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these ...