Entendiendo el archivo __init__.py en Python

Publicado por Andrea Navarro en

En este artículo explicaremos qué es el archivo __init__.py , cuál es su función dentro de los paquetes de Python, y cómo se relaciona con conceptos como módulo, paquete y biblioteca.

¿Qué es __init__.py?

__init__.py es un archivo especial que se coloca dentro de un paquete para indicar que esa carpeta debe ser tratada como tal. Sin este archivo, Python 2.x y versiones anteriores a la 3.3 no reconocen la carpeta como un paquete válido.

Para entender esto es necesario repasar los conceptos básicos, de módulo, paquete y biblioteca en Python:

  • Un módulo es cualquier archivo .py que contiene código Python.
  • Un paquete es una carpeta que contiene un conjunto de módulos relacionados.
  • Una biblioteca es un conjunto de módulos y paquetes que ofrecen funcionalidades específicas, y que pueden instalarse y usarse desde distintos proyectos (ej: numpy, requets, pandas, etc).

Si se tiene la siguiente estructura de proyecto:

mi_proyecto/
├── main.py
└── utilidades/
    ├── __init__.py
    ├── calculos.py
    └── funciones_texto.py

El archivo __init__.py dentro de la carpeta utilidades permite importar módulos completos, o algunas funciones de esos módulos. Para esto no es necesario que el archivo __init__ tenga ninguna clase de contenido.

from utilidades import calculos
from utilidades.funciones_texto import limpiar_texto

Contenido de __init__.py

Aunque técnicamente puede estar vacío, __init__.py puede contener código. Este archivo se puede utilizar para inicializar paquetes especificando su configuración y cargando recursos y para realizar importaciones internas de manera que sea mas sencillo acceder externamente a módulos del paquete y aquellos módulos que se encuentren dentro de otros paquetes.

Suponiendo la siguiente estructura de proyecto:

mi_proyecto/
├── main.py
└── utilidades/
    ├── __init__.py
    ├── calculos.py
    └── funciones_texto.py

Si es necesario cargar ciertas librerías que son utilizadas por todo el paquete utilidades, o realizar otro tipo de configuraciones, estas pueden ser detalladas dentro del archivo __init__.py de la siguiente manera:

print("Inicializando el paquete 'utilidades'...")

# Cargar librerías
import json
import pandas

Cada vez que se importe utilidades se ejecutarán estas líneas.

También es posible realizar importaciones internas para permitir importar funciones directamente, sin saber el contenido o estructura interna del paquete.

Suponiendo que el archivo calculos.py tiene una función llamada sumar, y el archivo funciones_texto.py tiene una función llamada limpiar_texto, es posible importarlas en __init__.py de la siguiente manera.

from .calculos import sumar
from .funciones_texto import limpiar_texto

Esto permitirá importar estas funciones directamente al importar la librería, y no será necesario hacer la importación absoluta.

#Importación absoluta si no se han importado las funciones en __init__
#from utilidades.calculos import sumar
#from utilidades.funciones_texto import limpiar_texto

#Importación con __init__ definido
from utilidades import sumar, limpiar_texto

Finalmente es posible especificar la lista __all__ que indica las partes del paquete que son públicas.

from .calculos import sumar
from .funciones_texto import limpiar_texto
__all__ = ["sumar", "limpiar_texto"]

Aunque esto no es recomendado, si se tiene definida la lista __all__ es posible importar todas las funciones de un paquete utilizando *:

from utilidades import *

¿Es necesario colocar el archivo __init__.py?

Desde Python 3.3, no es obligatorio tener un __init__.py para que una carpeta sea tratada como un paquete. Esto se debe a que se introdujeron los namespace packages, que permiten distribuir un paquete en múltiples ubicaciones del sistema de archivos sin necesidad del __init__.py.

Sin embargo, en la práctica es recomendable seguir usándolo ya que hace que la estructura del proyecto sea más clara y, por lo tanto, más sencilla de mantener.

Su existencia también mejora la compatibilidad con ciertas herramientas como editores o analizadores de código.

Finalmente, dentro de este archivo es posible controlar y configurar el comportamiento de un paquete cuando es importado.


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!

Categorías: Programación

Andrea Navarro

- Ingeniera en Informática - Docente universitaria - Investigadora