Advanced Class Patterns

Python OOPFree Lesson

Advertisement

Advanced Class Patterns

Metaclasses, descriptors, and class-level programming.

Overview

Master advanced class patterns.

Metaclasses

class RegistryMeta(type):
    _registry = {}
    
    def __new__(cls, name, bases, attrs):
        new_class = super().__new__(cls, name, bases, attrs)
        if name != 'Base':
            cls._registry[name] = new_class
        return new_class
    
    @classmethod
    def get_registry(cls):
        return cls._registry.copy()

class Base(metaclass=RegistryMeta):
    pass

class PluginA(Base):
    pass

class PluginB(Base):
    pass

print(RegistryMeta.get_registry())

Descriptors

class Validated:
    def __init__(self, min_value=None, max_value=None):
        self.min_value = min_value
        self.max_value = max_value
    
    def __set_name__(self, owner, name):
        self.name = name
    
    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        return getattr(obj, f'_{self.name}', None)
    
    def __set__(self, obj, value):
        if self.min_value is not None and value < self.min_value:
            raise ValueError(f"{self.name} must be >= {self.min_value}")
        if self.max_value is not None and value > self.max_value:
            raise ValueError(f"{self.name} must be <= {self.max_value}")
        setattr(obj, f'_{self.name}', value)

class Product:
    price = Validated(min_value=0)
    quantity = Validated(min_value=0, max_value=1000)
    
    def __init__(self, name, price, quantity):
        self.name = name
        self.price = price
        self.quantity = quantity

p = Product("Widget", 9.99, 100)
print(p.price)  # 9.99
# p.price = -5  # ValueError

Practice

Create a metaclass that adds logging to all methods.

Advertisement

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement