10 Practical Python Metaprogramming Scenarios Using __getattr__, __setattr__, and Descriptors
This article presents ten useful Python metaprogramming examples that demonstrate dynamic attribute access, setting, descriptor‑based validation, runtime attribute creation and deletion, computed properties, dynamic class and method generation, and metaclass techniques for flexible program behavior.
Metaprogramming in Python allows programs to create, modify, or control their own structure at runtime; the following ten examples illustrate common use‑cases with __getattr__ , __setattr__ , and property descriptors.
1. Dynamic attribute retrieval with __getattr__ :
class DynamicAttributes:
def __getattr__(self, name):
if name == "dynamic_attribute":
return "This is a dynamic attribute"
else:
raise AttributeError(f"{name} is not found")
obj = DynamicAttributes()
print(obj.dynamic_attribute) # This is a dynamic attribute
print(obj.undefined_attribute) # AttributeError: undefined_attribute is not found2. Dynamic attribute assignment with __setattr__ :
class DynamicAttributes:
def __setattr__(self, name, value):
print(f"Setting {name} to {value}")
super().__setattr__(name, value)
obj = DynamicAttributes()
obj.dynamic_attribute = 10 # Setting dynamic_attribute to 103. Attribute access control using a descriptor:
class PositiveNumber:
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if value <= 0:
raise ValueError("Value must be positive")
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class MyClass:
positive_number = PositiveNumber()
obj = MyClass()
obj.positive_number = 10
print(obj.positive_number) # 10
obj.positive_number = -5 # ValueError4. Dynamically creating an attribute with setattr :
class MyClass:
pass
obj = MyClass()
setattr(obj, "dynamic_attribute", 10)
print(obj.dynamic_attribute) # 105. Dynamically deleting an attribute with delattr :
class MyClass:
dynamic_attribute = 10
obj = MyClass()
delattr(obj, "dynamic_attribute")
print(obj.dynamic_attribute) # AttributeError6. Creating a computed property with the @property decorator:
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14 * self.radius ** 2
circle = Circle(5)
print(circle.area) # 78.57. Property with getter and setter for controlled access:
class PositiveNumber:
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if value <= 0:
raise ValueError("Value must be positive")
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class MyClass:
positive_number = PositiveNumber()
def __init__(self):
self._positive_number = 0
@property
def positive_number(self):
return self._positive_number
@positive_number.setter
def positive_number(self, value):
self._positive_number = value
obj = MyClass()
obj.positive_number = 10
print(obj.positive_number) # 10
obj.positive_number = -5 # ValueError8. Dynamically creating a class with type :
MyClass = type("MyClass", (), {"dynamic_attribute": 10})
obj = MyClass()
print(obj.dynamic_attribute) # 109. Dynamically adding a method using type :
def dynamic_method(self):
print("This is a dynamic method")
MyClass = type("MyClass", (), {"dynamic_method": dynamic_method})
obj = MyClass()
obj.dynamic_method() # This is a dynamic method10. Using a metaclass to provide dynamic attributes and methods:
class DynamicAttributes(type):
def __getattr__(cls, name):
if name == "dynamic_attribute":
return "This is a dynamic attribute"
raise AttributeError(f"{name} is not found")
def dynamic_method(cls):
print("This is a dynamic method")
class MyClass(metaclass=DynamicAttributes):
pass
obj = MyClass()
print(obj.dynamic_attribute) # This is a dynamic attribute
obj.dynamic_method() # This is a dynamic methodThese examples demonstrate how Python’s metaprogramming facilities can be leveraged for dynamic attribute handling, validation, computed properties, and runtime class or method generation, providing a flexible toolbox for advanced developers.
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.