Patrones de implementación práctica
Gestión dinámica de configuración
Clase de configuración con atributos dinámicos
class DynamicConfig:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
def update_config(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
## Usage example
config = DynamicConfig(debug=True, database='postgresql')
config.update_config(max_connections=100, timeout=30)
Patrón de validación de datos flexible
class ValidatedObject:
def __init__(self):
self._validators = {}
def add_validator(self, attribute, validator_func):
self._validators[attribute] = validator_func
def __setattr__(self, name, value):
if name in self._validators:
if not self._validators[name](value):
raise ValueError(f"Invalid value for {name}")
super().__setattr__(name, value)
## Example usage
def is_positive(x):
return x > 0
obj = ValidatedObject()
obj.add_validator('age', is_positive)
obj.age = 25 ## Works
## obj.age = -5 ## Raises ValueError
Seguimiento y registro de atributos
class AttributeTracker:
def __init__(self):
self._attribute_log = {}
def __setattr__(self, name, value):
if not name.startswith('_'):
self._attribute_log[name] = {
'value': value,
'timestamp': __import__('datetime').datetime.now()
}
super().__setattr__(name, value)
def get_attribute_history(self):
return self._attribute_log
Patrones de atributos dinámicos
Patrón |
Descripción |
Caso de uso |
Carga diferida (Lazy Loading) |
Crear atributos solo cuando se accede a ellos |
Optimización de recursos |
Propiedades calculadas (Computed Properties) |
Generar atributos de forma dinámica |
Cálculos complejos |
Proxy de atributos (Attribute Proxying) |
Redirigir el acceso a atributos |
Funcionalidad de middleware |
Patrón de proxy de atributos
class AttributeProxy:
def __init__(self, target):
self._target = target
self._interceptors = {}
def add_interceptor(self, attribute, interceptor_func):
self._interceptors[attribute] = interceptor_func
def __getattr__(self, name):
if name in self._interceptors:
return self._interceptors[name](self._target)
return getattr(self._target, name)
## Example usage
class User:
def __init__(self, name, role):
self.name = name
self.role = role
def role_checker(user):
return user.role == 'admin'
user = User('LabEx Admin', 'admin')
proxy = AttributeProxy(user)
proxy.add_interceptor('is_admin', role_checker)
Flujo de trabajo de atributos dinámicos
graph TD
A[Attribute Request] --> B{Interceptor Exists?}
B -->|Yes| C[Apply Interceptor]
B -->|No| D[Standard Attribute Access]
C --> E[Return Processed Value]
D --> E
Consideraciones avanzadas
- Implicaciones de rendimiento de los atributos dinámicos
- Gestión de memoria
- Seguridad de tipos
- Estrategias de manejo de errores
La implementación práctica de atributos dinámicos requiere un diseño cuidadoso y la consideración de casos de uso específicos y requisitos del sistema.