Explain Codes LogoExplain Codes Logo

Calling a function of a module by using its name (a string)

python
dynamic-invocation
getattr
importlib
Alex KataevbyAlex Kataev·Oct 6, 2024
TLDR

Invoke a function in a module using its string name through the built-in function getattr. Make sure that your module is already imported and double-check the function name to evade any hassles. Here’s a quick demonstration:

import mymodule result = getattr(mymodule, "my_function")() # Direct invocation

Exploring Python’s dynamic nature

The usage of getattr is only a single aspect of Python’s capabilities to dynamically invoke functions. Let’s explore more!

Dynamic Invocations in Global and Local Scopes

Ever heard of globals() and locals()?

Global Scope

globals() offers a dictionary reflecting the current global symbol table. Yes, Python’s dictionary of secrets!

# Assuming my_function is a social butterfly and is defined globally result = globals()["my_function"]() # Yay! Called from a string!

Local Scope

On the flip side, locals() returns a dictionary representing the current local symbol table, kind of like a private diary!

def my_secret(): def my_hidden_function(): return "Shhh...It's a secret function!" # Let's invoke the secrets return locals()["my_hidden_function"]() my_secret() # No more secret. Oops!

Dynamic Import of Modules and Function Calling

Need to import modules dynamically and call their functions? Python says, "No problem!"

import importlib module_name = "my_dynamite_module" function_name = "my_dynamite_function" module = importlib.import_module(module_name) result = getattr(module, function_name)() # Boom! Dynamite called!

Dynamically Invoking Class Methods

Creating class instances and calling methods can be dynamic too, thanks to Python’s versatility!

class_name = "MyCoolClass" method_name = "my_cool_method" MyCoolClass = globals()[class_name] instance = MyCoolClass() method = getattr(instance, method_name) # Ready to roll or what? result = method() # Rolling!

Dealing with Complex Structures

Hey, it’s Python! Dealing with complexities is just another day at the office!

full_path = "my_multi_stage_rocket_module.sub_module.MyClass.my_method" module_part, class_method = full_path.rsplit('.', 1) module = importlib.import_module(module_part) class_name, method_name = class_method.split('.') MyClass = getattr(module, class_name) result = getattr(MyClass(), method_name)() # Houston, we have a method!

Dynamically Executing Design Patterns

Capabilities extend to executing Singleton and Factory patterns dynamically too:

# Singleton pattern class SingletonMeta(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] # Factory pattern def factory(class_name): return globals()[class_name]() singleton_instance = factory("SingletonMeta") # Singleton, meet Python. Python, singleton.

The efficiency at which Python uses to execute powerful patterns optimises development speed and productivity.