Programación Modular

Ingeniería del Software para Inteligencia Artificial

Programación modular

  • La programación modular es una técnica de desarrollo que divide el código en módulos independientes y reutilizables.
  • Usando Python y POO, esto se logra mediante clases, módulos y paquetes, lo que facilita la organización y mantenibilidad del código.

  1. Encapsulamiento → Cada módulo oculta su implementación interna y solo expone una interfaz clara.
  2. Separación de Responsabilidades → Cada módulo o clase tiene una única responsabilidad.
  3. Reutilización de Código → Se pueden reutilizar clases y módulos en distintos proyectos.
  4. Bajo Acoplamiento → Los módulos deben interactuar con mínimas dependencias entre sí.
  5. Alta Cohesión → Cada módulo agrupa elementos que tienen un propósito común.

⚠️ ATENCIÓN ⚠️

Se deben evitar las dependencias circulares.

# modelo.py
from .datos import cargar_datos

def entrenar():
    datos = cargar_datos()
    # Entrena el modelo

def limpiar_datos(datos):
    # Preprocesa los datos
# datos.py
from .modelo import limpiar_datos # ❌ Dependencia circular

def cargar_datos():
    datos = leer_ficheros()
    datos = limpiar_datos(datos)
    return datos

Módulos

  • Un módulo es un archivo .py que contiene funciones, clases o variables reutilizables.
  • Permiten dividir el código en partes más pequeñas y manejables.
  • Se pueden importar con:
    • import nombre_modulo
    • from nombre_modulo import objeto

📂 /
│── 📄 modelo.py     # Módulo con la clase ModeloIA
└── 📄 main.py       # Módulo principal para ejecutar la aplicación
# modelo.py
class ModeloIA:
    def entrenar(self, datos):
        pass

    def predecir(self, entrada):
        pass
# main.py
from modelo import ModeloIA

modelo = ModeloIA()
modelo.entrenar(datos=[])

Paquetes

  • Un paquete es una carpeta que contiene múltiples módulos y un archivo especial __init__.py.
  • Permite organizar el código en una estructura modular y reutilizable.

📂 /
│── 📂 ml/               # Paquete de Machine Learning
│   │── 📄 __init__.py   # Indica que es un paquete
│   │── 📄 modelo.py     # Módulo con la clase ModeloIA
│   └── 📄 procesador.py # Módulo con la clase ProcesadorDatos
└── 📄 main.py           # Módulo principal para ejecutar la aplicación
# ml/__init__.py
from .modelo import ModeloIA
from .procesador import ProcesadorDatos
# main.py
from ml import ModeloIA, ProcesadorDatos

modelo = ModeloIA()
procesador = ProcesadorDatos()

El archivo __init__.py

  • __init__.py es un archivo especial que indica que un directorio debe tratarse como un paquete de Python.
  • Se encuentra dentro de las carpetas de paquetes y se ejecuta al importar el paquete.

Funciones de __init__.py

  1. Convertir un directorio en un paquete Python.
  2. Inicializar variables o configuraciones del paquete.
  3. Controlar qué módulos pueden importarse desde el paquete.
  4. Permite importaciones más limpias.

Importación con __init__.py

# ml/__init__.py
from .modelo import ModeloIA
from .procesador import ProcesadorDatos

# main.py
from ml import ModeloIA, ProcesadorDatos

Importación sin __init__.py

# main.py
from ml.modelo import ModeloIA
from ml.procesador import ProcesadorDatos

Importación relativa

Se usa . para importar módulos del mismo paquete.

from .modelo import ModeloIA
from .procesador import ProcesadorDatos

Importación absoluta

Se usa el nombre completo para importar módulos de otro paquete.

📂 /
│── 📂 ml/
│   │── 📄 __init__.py
│   └── 📄 modelo.py
└── 📂 data/
    │── 📄 __init__.py
    └── 📄 procesador.py
# modelo.py
from data import ProcesadorDatos # Si está exportado en __init__.py
from data.procesador import ProcesadorDatos # Importa directamente desde el módulo

¿Y si el código no está en la raíz del proyecto?

📂 /
│── 📂 src/
│   │── 📂 ml/
│   └── 📂 data/
└── 📂 tests/
# tests/test_modelo.py
from src.ml import Modelo # ⚠️ Cutre
# src/ml/modelo.py
from src.data import ProcesadorDatos # ❌ Problemas si instalamos el paquete

📂 /
│── 📂 .vscode
│   └── 📄 settings.json
│── 📂 src/
│── 📂 tests/
└── 📄 .env

.env

PYTHONPATH=src

.vscode/settings.json

{
    "python.analysis.extraPaths": ["src"]
}

📂 /
│── 📂 .vscode
│   └── 📄 settings.json
│── 📂 src/
│   │── 📂 ml/
│   └── 📂 data/
│── 📂 tests/
└── 📄 .env
# tests/test_modelo.py
from ml import Modelo # ✅ Más elegante
# src/ml/modelo.py
from data import ProcesadorDatos # ✅ Ahora funcionará siempre