Python Reflection and Metaprogramming: Concepts and Practical Examples
This article explains Python's reflection and metaprogramming features, demonstrating how to inspect objects, dynamically invoke methods, create classes, use metaclasses, decorators, exec, inspect signatures, and other advanced techniques through ten clear code examples.
Python's reflection and metaprogramming capabilities allow developers to inspect and manipulate program structures such as classes, methods, and variables at runtime, enabling dynamic behavior, code generation, framework construction, and automated testing.
Example 1: Retrieve an object's attributes and methods
def inspect_object(obj):
print(f"Attributes of {obj}:")
for attr in dir(obj):
if not attr.startswith("__"):
print(f" - {attr}")
inspect_object(str)Example 2: Dynamically call a method
class MyClass:
def greet(self, message):
print(message)
my_instance = MyClass()
method_name = "greet"
getattr(my_instance, method_name)("Hello, World!")Example 3: Dynamically create a class
class_dict = {
'say_hello': (lambda self: print("Hello from DynamicClass"))
}
DynamicClass = type('DynamicClass', (), class_dict)
instance = DynamicClass()
instance.say_hello()Example 4: Use a metaclass to customize class creation
class Meta(type):
def __new__(cls, name, bases, attrs):
attrs['class_name'] = name
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=Meta):
pass
print(MyClass.class_name)Example 5: Modify a class definition with a decorator
def add_attribute(attr_name, attr_value):
def decorator(cls):
setattr(cls, attr_name, attr_value)
return cls
return decorator
@add_attribute('my_attr', 'My Value')
class MyClass:
pass
print(MyClass.my_attr)Example 6: Use __metaclass__ (Python 2 style)
__metaclass__ = type
class MyClass:
def __init__(self):
self.class_name = self.__class__.__name__
print(MyClass().class_name)
# Note: In Python 3, __metaclass__ is deprecated; use the metaclass keyword instead.Example 7: Execute code strings dynamically with exec()
code = """
class MyClass:
def say_hello(self):
print("Hello from MyClass")
"""
exec(code)
my_instance = MyClass()
my_instance.say_hello()Example 8: Retrieve a function's signature using the inspect module
import inspect
def example_function(a, b, c=1):
pass
signature = inspect.signature(example_function)
print(signature)Example 9: Preserve decorator metadata with functools.wraps
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Before function call")
result = func(*args, **kwargs)
print("After function call")
return result
return wrapper
@my_decorator
def say_hello(name):
"""Says hello to the given name."""
print(f"Hello, {name}!")
print(say_hello.__name__)
print(say_hello.__doc__)Example 10: Obtain module information with the sys module
import sys
module_info = sys.modules[__name__]
print(f"Module Name: {module_info.__name__}")
print(f"Module Docstring: {module_info.__doc__}")The above examples illustrate common uses of Python reflection and metaprogramming; while powerful, they should be applied judiciously because they can make code harder to understand and debug. When used appropriately, these techniques greatly enhance flexibility and extensibility.
If you want to enrich your Python projects or dive deeper into the language's underlying mechanisms, exploring reflection and metaprogramming is highly worthwhile. Follow our WeChat subscription for more advanced Python topics.
Should you encounter any issues while trying the examples or wish to explore more complex metaprogramming scenarios, feel free to ask for help—I’m here to provide guidance.
Remember to balance the use of reflection and metaprogramming with code readability and maintainability; overuse may introduce unnecessary complexity. Reach out anytime if you have questions about striking that balance.
Test Development Learning Exchange
Test Development Learning Exchange
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.