Si tu archivo main.py ya parece un monstruo de mil líneas, aprender a crear paquetes en Python es el paso que transforma ese monolito en una aplicación profesional, ordenada y fácil de escalar. Aquí verás cómo agrupar módulos en paquetes usando el archivo __init__.py y cómo corregir los imports que se rompen al mover archivos.
Qué es un paquete en Python y por qué importa
Un paquete no es nada misterioso: es simplemente una carpeta que contiene un archivo especial. Ese detalle es lo que le dice a Python que esa carpeta puede agrupar módulos y comportarse como una unidad importable.
La clave está en el archivo __init__.py, que se nombra con dos guiones bajos, la palabra init y otros dos guiones bajos, con extensión .py [00:57]. Este archivo se ejecuta cada vez que un desarrollador importa el paquete, así que sirve para inicializar variables o configuraciones una sola vez.
¿Qué es el archivo __init__.py? Es el archivo que convierte una carpeta normal en un paquete de Python. Se ejecuta automáticamente al importar el paquete y puedes usarlo para inicializar variables o configuraciones.
En la clase se parte de una estructura plana, donde todos los archivos conviven en el mismo nivel, y se avanza hacia una estructura robusta separando el código en dos paquetes: examples para los ejemplos de clases anteriores y news_analyzer para la aplicación real.
Cómo organizar módulos en carpetas dentro de un proyecto
El primer movimiento es crear la carpeta examples, arrastrar allí todos los archivos de ejemplo y añadirle su __init__.py [01:39]. Con eso los tutoriales quedan aislados de la aplicación productiva.
Después se crea el paquete news_analyzer, que concentra la lógica de la app. Los nombres de paquetes siguen las mismas reglas que las variables en Python: usa guiones bajos y evita nombres arbitrarios [02:11].
Dentro de news_analyzer se movieron estos módulos:
news_api_client, el cliente que consume la news API.
exceptions, donde se crean clases de errores personalizadas.
config, con el API key y el base URL.
utils, con las utilidades de apoyo.
Una decisión importante: main.py se queda fuera, en la raíz o root del proyecto [02:34]. ¿Por qué? Porque así puedes ejecutar python main directamente desde la línea de comandos de tu editor sin rodeos. Con esto, el paquete news_analyzer queda completamente funcional y compartible, ya que no depende de los ejemplos para funcionar.
Cómo corregir imports al convertir tu app en paquetes
Aquí viene la parte que a todos nos ha roto un proyecto: mover archivos rompe los imports. Al mover config dentro de news_analyzer, el import debe apuntar a news_analyzer.config para llegar al API key y al base URL [03:11].
Cada punto separa niveles: le dices a Python que entre al paquete news_analyzer, luego al módulo config y ahí encuentre lo que necesitas. Incluso puedes anidar módulos dentro de módulos usando esa misma notación de puntos.
Un buen momento para refactorizar nombres: como el módulo news_api_client ya vive dentro del paquete, la palabra news se vuelve redundante y puede renombrarse a api_client [03:44]. La extensión Pylance detecta el cambio y actualiza automáticamente todos los imports asociados, dejando el código más legible.
Por qué necesitas importaciones relativas
Al ejecutar tras el refactor apareció el clásico error de módulo no encontrado [04:22]. El motivo: api_client buscaba config en el root del proyecto, cuando en realidad viven en el mismo paquete.
La solución es la importación relativa. Cuando un módulo importa a otro del mismo paquete, basta con anteponer un punto para indicar que ambos comparten ubicación [05:00]. Lo mismo aplica para exceptions.
¿Cuándo usar una importación relativa en Python? Cuando importas un módulo que vive en el mismo paquete que el archivo actual. Añades un punto antes del nombre, por ejemplo from .config import API_KEY, para que Python lo busque en el paquete correcto.
Y no olvides el orden que marca PEP 8: los imports relativos al propio paquete van de últimos y separados de los demás [05:20]. Tras aplicar esto, la aplicación vuelve a correr y retorna la primera página de noticias de la API.
Cómo escalar tu proyecto con paquetes anidados
La documentación oficial de Python muestra que puedes crear paquetes anidados sin límite [05:47]. Un paquete parent puede tener varios hijos, y cada hijo, a su vez, puede contener módulos y más paquetes. La única condición es que cada paquete tenga su propio __init__.py.
Esta organización te da tres ventajas concretas:
- Estructura clara, con separación entre la app y los tutoriales.
- Imports organizados, donde las clases creadas en
config o exceptions se reutilizan fácilmente en otros módulos.
- Escalabilidad, porque agregar una nueva funcionalidad se vuelve directo.
¿Qué es un paquete anidado? Es un paquete dentro de otro paquete. Cada nivel necesita su archivo __init__.py, y así puedes organizar aplicaciones grandes en jerarquías tan profundas como necesites.
El salto es real: pasaste de un main.py monolítico y sobrecargado a una aplicación estructurada en paquetes y módulos [06:33]. Eso te permite trabajar con más desarrolladores y crecer más rápido.
Como reto, entra al paquete examples, crea nuevos paquetes anidados y practica desde un archivo Python cómo importar cada uno de ellos [06:52]. ¿Ya intentaste renombrar un módulo y dejar que tu editor actualice los imports por ti? Cuéntame cómo te fue en los comentarios.